Skip to content
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

Speed up SipHasher128. #68914

Merged
merged 2 commits into from
Feb 12, 2020
Merged

Commits on Feb 10, 2020

  1. Speed up SipHasher128.

    The current code in `SipHasher128::short_write` is inefficient. It uses
    `u8to64_le` (which is complex and slow) to extract just the right number of
    bytes of the input into a u64 and pad the result with zeroes. It then
    left-shifts that value in order to bitwise-OR it with `self.tail`.
    
    For example, imagine we have a u32 input 0xIIHH_GGFF and only need three bytes
    to fill up `self.tail`. The current code uses `u8to64_le` to construct
    0x0000_0000_00HH_GGFF, which is just 0xIIHH_GGFF with the 0xII removed and
    zero-extended to a u64. The code then left-shifts that value by five bytes --
    discarding the 0x00 byte that replaced the 0xII byte! -- to give
    0xHHGG_FF00_0000_0000. It then then ORs that value with self.tail.
    
    There's a much simpler way to do it: zero-extend to u64 first, then left shift.
    E.g. 0xIIHH_GGFF is zero-extended to 0x0000_0000_IIHH_GGFF, and then
    left-shifted to 0xHHGG_FF00_0000_0000. We don't have to take time to exclude
    the unneeded 0xII byte, because it just gets shifted out anyway! It also avoids
    multiple occurrences of `unsafe`.
    
    There's a similar story with the setting of `self.tail` at the method's end.
    The current code uses `u8to64_le` to extract the remaining part of the input,
    but the same effect can be achieved more quickly with a right shift on the
    zero-extended input.
    
    All that works on little-endian. It doesn't work for big-endian, but we
    can just do a `to_le` before calling `short_write` and then it works.
    
    This commit changes `SipHasher128` to use the simpler shift-based approach. The
    code is also smaller, which means that `short_write` is now inlined where
    previously it wasn't, which makes things faster again. This gives big
    speed-ups for all incremental builds, especially "baseline" incremental
    builds.
    nnethercote committed Feb 10, 2020
    Configuration menu
    Copy the full SHA
    f8a0286 View commit details
    Browse the repository at this point in the history

Commits on Feb 12, 2020

  1. Improve u8to64_le.

    This makes it faster and also changes it to a safe function. (Thanks to
    Michael Woerister for the suggestion.) `load_int_le!` is also no longer
    necessary.
    nnethercote committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    9aea154 View commit details
    Browse the repository at this point in the history