-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: port in more from the C++ code #24
Conversation
bytes: [u8; 8], | ||
num: u64, | ||
} | ||
pub struct Symbol(u64); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
going from union -> newtype struct shows up in the cargo asm
. before symbol was getting spilled into stack, now it's passed in registers
#[cfg(miri)] | ||
const MAX_GENERATIONS: usize = 2; | ||
/// Entrypoint for building a new `Compressor`. | ||
pub struct CompressorBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
much of this is just moving the old methods from Compressor into a new struct
benches/micro.rs
Outdated
group.bench_function("compress-hashtab", |b| { | ||
// We create a symbol table and an input that will execute exactly one iteration, | ||
// in the fast compress_word pathway. | ||
let mut compressor = CompressorBuilder::new(); | ||
compressor.insert(Symbol::from_slice(b"abcdefgh"), 8); | ||
let compressor = compressor.build(); | ||
|
||
b.iter(|| unsafe { | ||
compressor.compress_into( | ||
b"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh", | ||
&mut output_buf, | ||
); | ||
}); | ||
}); | ||
|
||
group.bench_function("compress-twobytes", |b| { | ||
// We create a symbol table and an input that will execute exactly one iteration, | ||
// in the fast compress_word pathway. | ||
let mut compressor = CompressorBuilder::new(); | ||
compressor.insert(Symbol::from_slice(&[b'a', b'b', 0, 0, 0, 0, 0, 0]), 8); | ||
let compressor = compressor.build(); | ||
|
||
b.iter(|| unsafe { | ||
compressor.compress_into(b"abababababababab", &mut output_buf); | ||
}); | ||
}); | ||
group.finish(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// a load of `N` values from the pointer in a minimum number of instructions into | ||
/// an output `u64`. | ||
#[inline] | ||
unsafe fn extract_u64<const N: usize>(ptr: *const u8) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With better benchmarking it became clear this had no effect on performance VS just doing a copy_non_overlapping, and was less clear in general
## 🤖 New release * `fsst-rs`: 0.2.3 -> 0.3.0 <details><summary><i><b>Changelog</b></i></summary><p> <blockquote> ## [0.3.0](v0.2.3...v0.3.0) - 2024-09-03 ### Added - port in more from the C++ code ([#24](#24)) ### Other - centering ([#26](#26)) </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/MarcoIeni/release-plz/). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR ports in some more functionality based on the MIT-licensed C++ code from CWI.
In particular, it implements the following:
makeSample
function from C++ to build a sample of ~16KB from the input datasuffix limit
optimization and its correspondingfinalize
method needed when building the symbol table, including changes to thecompress_word
function we have that more directly corresponds to thecompressVariant
from the C++ codebyteCodes
from C++, which we implement here ascodes_one_byte
. Note that before this PR, one-byte codes would not be found unless the byte occurred at the end of the plaintext stringCompressor
build state into a newCompressorBuilder
struct, which has all methods that take&mut self
. This also means that we can in theory construct aCompressor
now from a symbol table, though that logic is not implemented.Additional things in this PR:
compress_word
method comparing the relative speeds of both code paths, see feat: port in more from the C++ code #24 (comment)dbtext
compression benchmarks from the CWI paper. Here's a table of the compression factors:I'll follow up to figure out how to close the gap with those 1-2% differences