optimzed SipHash implementation#13522
Conversation
|
Nice wins. |
|
It's really awesome to have this running faster on small keys, because it will discourage working around the issue by using hashes vulnerable to DoS attacks. I wonder how much more there is to gain here. |
There was a problem hiding this comment.
why not a for loop? (And why not use the vector iterator + .enumerate() to avoid the bounds checks?)
There was a problem hiding this comment.
I thought of usingusing a range iter, but a cursory glance made me think it brought more overhead and branches. I'll try a bench using for, and if it's faster, I can switch it.
There was a problem hiding this comment.
I was thinking something to avoid the indexing with the associated bounds checks and unwinding, something like:
for (t, x) in $buf.slice($i, $i + $len).enumerate() {
out |= *x << t * 8
}There was a problem hiding this comment.
Changing to that added 2ns/iter to each bench.
|
@thestinger I wonder as well. I'm putting together a bench of a straight I'm wondering if we could sacrifice some memory for speed by collecting all |
|
It's possible to do a lot better than the plain single-pass C implementation by using SIMD. |
|
This appeared to cause a test failure on windows: http://buildbot.rust-lang.org/builders/auto-win-32-nopt-t/builds/4459/steps/test/logs/stdio. Perhaps there's a bug on 32-bit? |
work started from @gereeter's PR: rust-lang#13114 but adjusted bits
|
@alexcrichton yep, hash of |
|
I was worried about #8361 cropping up again, but it appears that's what happened before anyway, so I'm not too worried. |
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`).
…=lnicola fix: disregard type variable expectation for if expressions Fixes rust-lang#13522 As [the comment](https://github.com/rust-lang/rust-analyzer/blob/8142d1f606dc2e52b1d2b8992671e2bd73379f28/crates/hir-ty/src/infer.rs#L1087-L1090) on `Expectation::adjust_for_branches` explains: > If the expected type is just a type variable, then don't use an expected type. Otherwise, we might write parts of the type when checking the 'then' block which are incompatible with the 'else' branch. Note that we already use it in match expressions. I've added tests for them too nevertheless.
work started from @gereeter's PR: #13114
but adjusted bits
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
intandu64).