srijs/rusha — pull request #5 by edwintorok (2013-04-03 20:59:38+00:00)
Title: Optimize by unrolling: ~2x speedup

Move the bigendian conversion inside the asm.js code, and fully unroll all the rounds of SHA1.

This leads to quite significant performance improvement on my test box (Linux x86_64, Phenom II X6, Firefox nightly), for example on the 1MB test:
Current upstream code:

[23:50:13.861] Rusha emitted 41e51b24acd11432b7cd547960812230a0c04c4a in
12.333333333333334 milliseconds

After my optimizations:

[23:52:03.530] Rusha emitted 9c6a7835be5e32acad3492240e9c188b84d7f3bc in
6.333333333333333 milliseconds

For reference the "native" nodejs crypto speed is (but that uses OpenSSL's assembly implementation probably):

Native emitted fa77db6cbf99a9d53ec376f8cd41c03a51cae110 in 2.3333333333333335 milliseconds

Note: the pull request also includes the bugfix from 'fix-padlen', and the tests still pass after the optimizations.

Here is the full benchmark output from before:

[23:50:13.099] Benchmarking 4096 bytes ...
[23:50:13.100] Native emitted unavailableunavailableunavailableunavail in 0
milliseconds
[23:50:13.108] Rusha emitted 742bcb6d44b34010acc487b71792b4bd042ee227 in 0.08
milliseconds
[23:50:13.144] Johnst. emitted 742bcb6d44b34010acc487b71792b4bd042ee227 in 0.36
milliseconds
[23:50:13.238] Cifre emitted 742bcb6d44b34010acc487b71792b4bd042ee227 in 0.93
milliseconds
[23:50:13.238] Benchmarking 65535 bytes ...
[23:50:13.240] Native emitted unavailableunavailableunavailableunavail in 0
milliseconds
[23:50:13.264] Rusha emitted 82d7e001b991ae86161c6487fb895aa1cae67bde in 0.8
milliseconds
[23:50:13.408] Johnst. emitted 82d7e001b991ae86161c6487fb895aa1cae67bde in 4.8
milliseconds
[23:50:13.793] Cifre emitted 82d7e001b991ae86161c6487fb895aa1cae67bde in
12.833333333333334 milliseconds
[23:50:13.794] Benchmarking 1048576 bytes ...
[23:50:13.823] Native emitted unavailableunavailableunavailable in 0
milliseconds
[23:50:13.861] Rusha emitted 41e51b24acd11432b7cd547960812230a0c04c4a in
12.333333333333334 milliseconds
[23:50:14.088] Johnst. emitted 41e51b24acd11432b7cd547960812230a0c04c4a in
75.66666666666667 milliseconds
[23:50:14.701] Cifre emitted 41e51b24acd11432b7cd547960812230a0c04c4a in
204.33333333333334 milliseconds
[23:50:14.702] Benchmarking 4194304 bytes ...
[23:50:14.816] Native emitted unavailable in 0 milliseconds
[23:50:14.866] Rusha emitted 0c47debe87bcc382f5623f93cce128bb728146a7 in 50
milliseconds
[23:50:15.171] Johnst. emitted 0c47debe87bcc382f5623f93cce128bb728146a7 in 305
milliseconds
[23:50:15.990] Cifre emitted 0c47debe87bcc382f5623f93cce128bb728146a7 in 819
milliseconds
[23:50:15.990] Benchmarking 8388608 bytes ...
[23:50:16.215] Native emitted unavailable in 0 milliseconds
[23:50:16.315] Rusha emitted d003e17580ebe2b708c86d3cdc6ba1cae44d5fc6 in 100
milliseconds
[23:50:16.931] Johnst. emitted d003e17580ebe2b708c86d3cdc6ba1cae44d5fc6 in 616
milliseconds
[23:50:18.574] Cifre emitted d003e17580ebe2b708c86d3cdc6ba1cae44d5fc6 in 1643
milliseconds

And after:

[23:52:02.789] Error: Successfully compiled asm.js code
[23:52:02.802] Benchmarking 4096 bytes ...
[23:52:02.803] Native emitted unavailableunavailableunavailableunavail in 0
milliseconds
[23:52:02.809] Rusha emitted fd892dbc7cc8c12b734a4090889f0b0065f70caf in 0.06
milliseconds
[23:52:02.846] Johnst. emitted fd892dbc7cc8c12b734a4090889f0b0065f70caf in 0.37
milliseconds
[23:52:02.939] Cifre emitted fd892dbc7cc8c12b734a4090889f0b0065f70caf in 0.93
milliseconds
[23:52:02.939] Benchmarking 65535 bytes ...
[23:52:02.941] Native emitted unavailableunavailableunavailableunavail in 0
milliseconds
[23:52:02.953] Rusha emitted 7b7968b20a131d028a69bd10e1930b8f0f628001 in 0.4
milliseconds
[23:52:03.098] Johnst. emitted 7b7968b20a131d028a69bd10e1930b8f0f628001 in
4.833333333333333 milliseconds
[23:52:03.482] Cifre emitted 7b7968b20a131d028a69bd10e1930b8f0f628001 in 12.8
milliseconds
[23:52:03.483] Benchmarking 1048576 bytes ...
[23:52:03.511] Native emitted unavailableunavailableunavailable in 0
milliseconds
[23:52:03.530] Rusha emitted 9c6a7835be5e32acad3492240e9c188b84d7f3bc in
6.333333333333333 milliseconds
[23:52:03.748] Johnst. emitted 9c6a7835be5e32acad3492240e9c188b84d7f3bc in
72.66666666666667 milliseconds
[23:52:04.364] Cifre emitted 9c6a7835be5e32acad3492240e9c188b84d7f3bc in 205
milliseconds
[23:52:04.365] Benchmarking 4194304 bytes ...
[23:52:04.476] Native emitted unavailable in 0 milliseconds
[23:52:04.503] Rusha emitted 58fd426cd230c8024c81c622dc2a4548fff61200 in 27
milliseconds
[23:52:04.799] Johnst. emitted 58fd426cd230c8024c81c622dc2a4548fff61200 in 295
milliseconds
[23:52:05.616] Cifre emitted 58fd426cd230c8024c81c622dc2a4548fff61200 in 817
milliseconds
[23:52:05.616] Benchmarking 8388608 bytes ...
[23:52:05.837] Native emitted unavailable in 0 milliseconds
[23:52:05.892] Rusha emitted bd867184a55277a6128bf75d9f286db0f7db37c7 in 53
milliseconds
[23:52:06.502] Johnst. emitted bd867184a55277a6128bf75d9f286db0f7db37c7 in 610
milliseconds
[23:52:08.142] Cifre emitted bd867184a55277a6128bf75d9f286db0f7db37c7 in 1640
milliseconds

And NodeJS timings (after):

Native emitted 1de513f736e24c19bee1755514fa6e3e3ea97aa7 in 0.02 milliseconds
Rusha emitted 1de513f736e24c19bee1755514fa6e3e3ea97aa7 in 7.23 milliseconds
Johnst. emitted 1de513f736e24c19bee1755514fa6e3e3ea97aa7 in 0.85 milliseconds
Cifre emitted 1de513f736e24c19bee1755514fa6e3e3ea97aa7 in 1.41 milliseconds
Benchmarking 65535 bytes ...
Native emitted 114a405808fc29f0b4a4c44952f78a14dbe37cd5 in 0.13333333333333333 milliseconds
Rusha emitted 114a405808fc29f0b4a4c44952f78a14dbe37cd5 in 28.7 milliseconds
Johnst. emitted 114a405808fc29f0b4a4c44952f78a14dbe37cd5 in 12.733333333333333 milliseconds
Cifre emitted 114a405808fc29f0b4a4c44952f78a14dbe37cd5 in 18.333333333333332 milliseconds
Benchmarking 1048576 bytes ...
Native emitted fa77db6cbf99a9d53ec376f8cd41c03a51cae110 in 2.3333333333333335 milliseconds
Rusha emitted fa77db6cbf99a9d53ec376f8cd41c03a51cae110 in 457 milliseconds
Johnst. emitted fa77db6cbf99a9d53ec376f8cd41c03a51cae110 in 218 milliseconds
Cifre emitted fa77db6cbf99a9d53ec376f8cd41c03a51cae110 in 294 milliseconds
Benchmarking 4194304 bytes ...
Native emitted a98ef4dc68689e95c849bc0c0ecaf74c1ed2b7fc in 9 milliseconds
Rusha emitted a98ef4dc68689e95c849bc0c0ecaf74c1ed2b7fc in 1843 milliseconds
Johnst. emitted a98ef4dc68689e95c849bc0c0ecaf74c1ed2b7fc in 923 milliseconds
Cifre emitted a98ef4dc68689e95c849bc0c0ecaf74c1ed2b7fc in 1172 milliseconds
Benchmarking 8388608 bytes ...
Native emitted 7cf763dcfd71073c168ba7c22586ff4f8935d83c in 18 milliseconds
Rusha emitted 7cf763dcfd71073c168ba7c22586ff4f8935d83c in 3654 milliseconds
Johnst. emitted 7cf763dcfd71073c168ba7c22586ff4f8935d83c in 1734 milliseconds
Cifre emitted 7cf763dcfd71073c168ba7c22586ff4f8935d83c in 2365 milliseconds