Skip to content

Conversation

@dearblue
Copy link
Contributor

@dearblue dearblue commented Jul 8, 2023

The generic Digest::CRC#update method is provided, eliminating the need to define separate #updates for many CRCs.
However, the Digest::CRC::REFLECT_INPUT constant must be overridden by true or false.

To speed things up a bit, the following is made:

  • Use local variables instead of instance variables inside loops.
  • Suppress generation of multi-precision integers.

I'm not particular about the name of REFLECT_INPUT, so if anyone has any suggestions, I'll change it.

@dearblue
Copy link
Contributor Author

dearblue commented Jul 8, 2023

For reference, I am attaching the benchmark results measured on my PC.

  • Please note that there are a number of background processes running, which may affect the results to some degree.
  • The "real" benchmark output is taken out.
  • The binary package ruby 3.2 provided by the FreeBSD project has YJIT disabled, so ruby 3.1 is used instead.
  • | ruby32 -v | ruby 3.2.2 (2023-03-30 revision e51014f9c0) [amd64-freebsd13]
    | ruby31 -v | ruby 3.1.4p223 (2023-03-30 revision 957bb7cb81) [amd64-freebsd13]
    | jruby -v | jruby 9.2.17.0 (2.5.8) 2021-03-29 84d363da97 OpenJDK 64-Bit Server VM 25.372-b07 on 1.8.0_372-b07 +jit [freebsd-x86_64]
ruby32 ruby31 --yjit jruby
main this PR main this PR main this PR
Digest::CRC1#update 0.413156 0.450639 0.400173 0.392028 0.312848 0.344441
Digest::CRC5#update 1.471989 0.701404 0.682974 0.467105 0.639566 0.378853
Digest::CRC8#update 1.426721 1.002237 0.701005 0.535166 0.656496 0.438962
Digest::CRC8_1Wire#update 1.435443 0.979240 0.785536 0.530573 0.658349 0.377159
Digest::CRC15#update 1.751928 1.721342 0.779405 0.666303 0.700163 0.700162
Digest::CRC16#update 1.402283 1.339391 0.733769 0.564226 0.710644 0.406121
Digest::CRC16CCITT#update 1.740074 1.661728 0.691878 0.707596 0.740250 0.789879
Digest::CRC16DNP#update 1.341073 1.264648 0.681094 0.566660 0.512899 0.392202
Digest::CRC16Genibus#update 1.822862 1.677790 0.734139 0.706260 0.730047 0.660704
Digest::CRC16Modbus#update 1.388758 1.325434 0.712974 0.587603 0.568764 0.383336
Digest::CRC16QT#update 1.409243 1.268288 0.697429 0.566340 0.512600 0.437730
Digest::CRC16USB#update 1.394310 1.283062 0.790167 0.569061 0.552077 0.384195
Digest::CRC16X25#update 1.397066 1.323211 0.734347 0.566696 0.510791 0.417712
Digest::CRC16XModem#update 1.776022 1.782290 0.731255 0.709042 0.720106 0.665169
Digest::CRC16ZModem#update 1.810085 1.664810 0.732177 0.696851 0.673232 0.607033
Digest::CRC24#update 1.783538 1.689062 0.730286 0.667194 0.760796 0.672397
Digest::CRC32#update 1.386887 1.287927 0.723988 0.628428 0.615478 0.432369
Digest::CRC32BZip2#update 1.761105 1.711941 0.737906 0.725438 0.660596 0.661087
Digest::CRC32c#update 1.375790 1.347202 0.742967 0.597620 0.598534 0.418801
Digest::CRC32Jam#update 1.377057 1.298975 0.689968 0.575938 0.654536 0.424091
Digest::CRC32MPEG#update 1.769699 1.696188 0.761883 0.665675 0.627799 0.660462
Digest::CRC32POSIX#update 1.728269 1.660507 0.759890 0.660590 0.690486 0.688585
Digest::CRC32XFER#update 1.754600 1.678388 0.750021 0.701695 0.649378 0.688124
Digest::CRC64#update 3.504403 2.392109 2.272752 2.050897 2.108015 1.356082
Digest::CRC64Jones#update 3.461163 2.438005 2.322609 2.079037 2.145611 1.186643
Digest::CRC64XZ#update 3.447103 2.464268 2.344339 2.113575 2.077718 1.155891

Comment on lines 113 to 122
crc = @crc

if self.class::REFLECT_INPUT
if @width > 8
data.each_byte do |b|
crc = table[b ^ (0xff & crc)] ^ (crc >> 8)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we trust each element of @table, we can make just one more speed improvement:

-      crc = @crc
+      crc = @crc & ~(-1 << @width)

       if self.class::REFLECT_INPUT
         if @width > 8
           data.each_byte do |b|
-            crc = table[b ^ (0xff & crc)] ^ (crc >> 8)
+            crc = table[b ^ crc] ^ (crc >> 8)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my earlier comment is wrong.
0xff & ... can be removed in three places except above.

Copy link
Owner

@postmodern postmodern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor changes requested. Need a @raise YARD tag explaining when NotImplementedError will be raised. Also some specs for that logic. Also some questions about variable naming.

@postmodern
Copy link
Owner

I also noticed your using self.class::CONST. Should we replace self.class.const_get(:CONST) with self.class::CONST?

@postmodern
Copy link
Owner

I also thought about recommending code styling changes:

  • Vertically align =
  • Add an extra newline between assignments and data.each_byte statement.

@dearblue
Copy link
Contributor Author

Thank you for review. I will fix it.

The generic `Digest::CRC#update` method is provided, eliminating the need to define separate `#updates` for many CRCs.
However, the `Digest::CRC::REFLECT_INPUT` constant must be overridden by `true` or `false`.

To speed things up a bit, the following is made:

  - Use local variables instead of instance variables inside loops.
  - Suppress generation of multi-precision integers.
@dearblue dearblue force-pushed the unified-crc-update branch from 57c5624 to 62995d4 Compare July 12, 2023 14:20
@postmodern postmodern merged commit 91ee75f into postmodern:main Jul 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants