-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Optimized SipHash implementation #13114
Conversation
} | ||
|
||
#[inline] | ||
fn write_le_u16(&mut self, n: u16) -> IoResult<()> { |
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.
Are these still correct on a big-endian platform?
Also, I feel like these could be abstracted slightly (e.g. by a macro or a function taking n: u64
and length: uint
), since the only (significant) difference between all these new writes is the 1
/2
/4
/8
.
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.
It would also be nice to have a comment explaining why they're overwritten.
bench_compound_1: 70 -> 56 bench_long_str: 795 -> 525 bench_str: 32 -> 32
…implementation to get the same benifits as the previous try using unsafe code.
I moved all the bytes to Incidentally, why are |
copy_nonoverlapping_memory(out, ptr, size); | ||
from_le64(*(out as *i64)) as 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.
This and the above function look quite similar, perhaps they could be refactored? Could the byte-swapping intrinsics be used in combination with reading using the big endian function?
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.
I'd rather define the big endian function in terms of the little endian function, as the little endian function is slightly simpler, but merging seems reasonable, even if it breaks symmetry.
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.
Either way is fine by me, I'd just shoot for less duplication.
Closing due to inactivity, but feel free to reopen with a rebase! |
work started from @gereeter's PR: rust-lang#13114 but adjusted bits
work started from @gereeter's PR: #13114 but adjusted bits ``` before test hash::sip::tests::bench_u64 ... bench: 34 ns/iter (+/- 0) test hash::sip::tests::bench_str_under_8_bytes ... bench: 37 ns/iter (+/- 1) test hash::sip::tests::bench_str_of_8_bytes ... bench: 43 ns/iter (+/- 1) test hash::sip::tests::bench_str_over_8_bytes ... bench: 50 ns/iter (+/- 1) test hash::sip::tests::bench_long_str ... bench: 613 ns/iter (+/- 14) test hash::sip::tests::bench_compound_1 ... bench: 114 ns/iter (+/- 11) after test hash::sip::tests::bench_u64 ... bench: 25 ns/iter (+/- 0) test hash::sip::tests::bench_str_under_8_bytes ... bench: 31 ns/iter (+/- 0) test hash::sip::tests::bench_str_of_8_bytes ... bench: 36 ns/iter (+/- 0) test hash::sip::tests::bench_str_over_8_bytes ... bench: 40 ns/iter (+/- 0) test hash::sip::tests::bench_long_str ... bench: 600 ns/iter (+/- 14) test hash::sip::tests::bench_compound_1 ... bench: 64 ns/iter (+/- 6) ``` Notably it seems smaller keys will hash faster. A long string doesn't see much gains, but compound cuts in half (once compound used a `int` and `u64`).
This makes hashing a fair bit faster for long strings and non-string objects:
This helps with #11783.