improve slope calculation by delaying f64 cast

This commit is contained in:
Pascal Seitz
2022-08-11 10:42:14 +02:00
parent 31ba5a3c16
commit 9811d15657
3 changed files with 21 additions and 6 deletions

View File

@@ -97,7 +97,16 @@ pub(crate) fn get_slope(first_val: u64, last_val: u64, num_vals: u64) -> f32 {
}
// We calculate the slope with f64 high precision and use the result in lower precision f32
// This is done in order to handle estimations for very large values like i64::MAX
((last_val as f64 - first_val as f64) / (num_vals as u64 - 1) as f64) as f32
let diff = diff(last_val, first_val);
(diff / (num_vals as u64 - 1) as f64) as f32
}
fn diff(val1: u64, val2: u64) -> f64 {
if val1 >= val2 {
(val1 - val2) as f64
} else {
(val2 - val1) as f64 * -1.0
}
}
#[inline]

View File

@@ -16,7 +16,7 @@ use std::ops::Sub;
use common::{BinarySerializable, CountingWriter, DeserializeFrom};
use tantivy_bitpacker::{compute_num_bits, BitPacker, BitUnpacker};
use crate::linearinterpol::{get_calculated_value, get_slope};
use crate::linearinterpol::get_slope;
use crate::{FastFieldCodecReader, FastFieldCodecSerializer, FastFieldDataAccess, FastFieldStats};
const CHUNK_SIZE: u64 = 512;
@@ -356,6 +356,11 @@ fn distance<T: Sub<Output = T> + Ord>(x: T, y: T) -> T {
}
}
#[inline]
fn get_calculated_value(first_val: u64, pos: u64, slope: f32) -> u64 {
(first_val as i64 + (pos as f32 * slope) as i64) as u64
}
#[cfg(test)]
mod tests {
use super::*;
@@ -375,11 +380,11 @@ mod tests {
#[test]
fn test_compression_i64() {
let data = (-10..=6_000_i64)
.map(|el| i64_to_u64(el))
let data = (i64::MAX - 600_000..=i64::MAX - 550_000)
.map(i64_to_u64)
.collect::<Vec<_>>();
let (estimate, actual_compression) =
create_and_validate(&data, "simple monotonically large");
create_and_validate(&data, "simple monotonically large i64");
assert!(actual_compression < 0.2);
assert!(estimate < 0.20);
assert!(estimate > 0.15);

View File

@@ -469,7 +469,8 @@ mod tests {
}
let file = directory.open_read(path).unwrap();
// assert_eq!(file.len(), 17710 as usize); //bitpacked size
assert_eq!(file.len(), 10175_usize); // linear interpol size
// assert_eq!(file.len(), 10175_usize); // linear interpol size
assert_eq!(file.len(), 75_usize); // linear interpol size after calc improvement
{
let fast_fields_composite = CompositeFile::open(&file)?;
let data = fast_fields_composite.open_read(i64_field).unwrap();