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

feat: add swappable hasher, default to noble-hashes #314

Merged
merged 5 commits into from
Apr 5, 2023

Conversation

wemeetagain
Copy link
Member

Motivation

See #313

We can replace as-sha256 with noble-hashes as long as we support our current interfaces and expose some mechanism to update the implementation for Lodestar's sake.

Its likely overkill to pass hash functions down thru our stack, and we can assume that a runtime will only require a single hash implementation.

Description

  • Replace as-sha256 (and avoid loading any wasm) with noble-hashes sha256 implementation by default.
  • Add a swapable "hasher" that can be updated before importing the persistent-merkle-tree / ssz or consumer libraries

Swapping the hasher with as-sha256, as will be required by lodestar, can be done like so:

// in lodestar, before anything else

import {hasher} from "@chainsafe/persistent-merkle-tree/hasher/as-sha256";
import {setHasher} from "@chainsafe/persistent-merkle-tree/hasher";

setHasher(hasher);

await import("./the-rest-of-the-application.js");

Benchmarks

Feel free to figure out how to speed this up if desired. I might be doing something stupid here.

yarn benchmark:files packages/persistent-merkle-tree/test/perf/hasher.test.ts

  hasher
    ✓ hash 2 Uint8Array 2250026 times - as-sha256                        0.4682371 ops/s    2.135670  s/op        -         12 runs   27.7 s
    ✓ hashTwoObjects 2250026 times - as-sha256                           0.4947299 ops/s    2.021305  s/op        -         12 runs   26.3 s
    ✓ hash 2 Uint8Array 2250026 times - noble                            0.1935327 ops/s    5.167086  s/op        -         11 runs   61.7 s
    ✓ hashTwoObjects 2250026 times - noble                               0.1418410 ops/s    7.050149  s/op        -          8 runs   63.4 s

@github-actions
Copy link

github-actions bot commented Mar 25, 2023

⚠️ Performance Alert ⚠️

Possible performance regression was detected for some benchmarks.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold.

Benchmark suite Current: 515564a Previous: dbae75a Ratio
250k validators 14.081 s/op 3.0091 s/op 4.68
Full benchmark results
Benchmark suite Current: 515564a Previous: dbae75a Ratio
digestTwoHashObjects 50023 times 75.721 ms/op 57.908 ms/op 1.31
digest64 50023 times 76.491 ms/op 60.642 ms/op 1.26
digest 50023 times 75.073 ms/op 60.606 ms/op 1.24
input length 32 1.8710 us/op 1.5280 us/op 1.22
input length 64 2.0060 us/op 1.5890 us/op 1.26
input length 128 3.4820 us/op 2.8480 us/op 1.22
input length 256 5.1770 us/op 4.1620 us/op 1.24
input length 512 8.6250 us/op 6.7530 us/op 1.28
input length 1024 16.781 us/op 13.478 us/op 1.25
digest 1000000 times 1.3024 s/op 1.0406 s/op 1.25
hashObjectToByteArray 50023 times 2.9891 ms/op 2.3770 ms/op 1.26
byteArrayToHashObject 50023 times 3.3612 ms/op 3.0661 ms/op 1.10
getGindicesAtDepth 7.4520 us/op 6.6290 us/op 1.12
iterateAtDepth 15.489 us/op 13.377 us/op 1.16
getGindexBits 700.00 ns/op 604.00 ns/op 1.16
gindexIterator 1.5060 us/op 1.3960 us/op 1.08
hash 2 Uint8Array 2250026 times - as-sha256 3.4086 s/op
hashTwoObjects 2250026 times - as-sha256 3.2789 s/op
hash 2 Uint8Array 2250026 times - noble 10.704 s/op
hashTwoObjects 2250026 times - noble 13.200 s/op
getNodeH() x7812.5 avg hindex 30.629 us/op 20.853 us/op 1.47
getNodeH() x7812.5 index 0 10.667 us/op 8.1650 us/op 1.31
getNodeH() x7812.5 index 7 10.693 us/op 8.1220 us/op 1.32
getNodeH() x7812.5 index 7 with key array 10.710 us/op 8.1900 us/op 1.31
new LeafNode() x7812.5 370.00 us/op 145.59 us/op 2.54
multiproof - depth 15, 1 requested leaves 18.400 us/op 10.774 us/op 1.71
tree offset multiproof - depth 15, 1 requested leaves 40.267 us/op 25.138 us/op 1.60
compact multiproof - depth 15, 1 requested leaves 9.9400 us/op 4.0590 us/op 2.45
multiproof - depth 15, 2 requested leaves 23.941 us/op 16.570 us/op 1.44
tree offset multiproof - depth 15, 2 requested leaves 42.211 us/op 30.683 us/op 1.38
compact multiproof - depth 15, 2 requested leaves 5.9470 us/op 4.0690 us/op 1.46
multiproof - depth 15, 3 requested leaves 33.435 us/op 23.887 us/op 1.40
tree offset multiproof - depth 15, 3 requested leaves 55.880 us/op 40.350 us/op 1.38
compact multiproof - depth 15, 3 requested leaves 9.9460 us/op 6.2660 us/op 1.59
multiproof - depth 15, 4 requested leaves 44.199 us/op 40.660 us/op 1.09
tree offset multiproof - depth 15, 4 requested leaves 69.037 us/op 54.906 us/op 1.26
compact multiproof - depth 15, 4 requested leaves 10.643 us/op 8.4230 us/op 1.26
packedRootsBytesToLeafNodes bytes 4000 offset 0 4.3350 us/op 3.8120 us/op 1.14
packedRootsBytesToLeafNodes bytes 4000 offset 1 4.1200 us/op 3.8500 us/op 1.07
packedRootsBytesToLeafNodes bytes 4000 offset 2 4.1190 us/op 3.6950 us/op 1.11
packedRootsBytesToLeafNodes bytes 4000 offset 3 4.1490 us/op 3.6790 us/op 1.13
subtreeFillToContents depth 40 count 250000 101.40 ms/op 92.567 ms/op 1.10
setRoot - gindexBitstring 15.967 ms/op 15.222 ms/op 1.05
setRoot - gindex 16.444 ms/op 15.731 ms/op 1.05
getRoot - gindexBitstring 4.5094 ms/op 3.0653 ms/op 1.47
getRoot - gindex 5.2419 ms/op 3.9964 ms/op 1.31
getHashObject then setHashObject 18.651 ms/op 17.667 ms/op 1.06
setNodeWithFn 15.965 ms/op 15.572 ms/op 1.03
getNodeAtDepth depth 0 x100000 2.8495 ms/op 2.1908 ms/op 1.30
setNodeAtDepth depth 0 x100000 4.9936 ms/op 4.4174 ms/op 1.13
getNodesAtDepth depth 0 x100000 2.2450 ms/op 1.9455 ms/op 1.15
setNodesAtDepth depth 0 x100000 3.1753 ms/op 2.4256 ms/op 1.31
getNodeAtDepth depth 1 x100000 2.8427 ms/op 2.3653 ms/op 1.20
setNodeAtDepth depth 1 x100000 11.391 ms/op 10.292 ms/op 1.11
getNodesAtDepth depth 1 x100000 2.6133 ms/op 2.0056 ms/op 1.30
setNodesAtDepth depth 1 x100000 9.2575 ms/op 8.2749 ms/op 1.12
getNodeAtDepth depth 2 x100000 3.5029 ms/op 2.7978 ms/op 1.25
setNodeAtDepth depth 2 x100000 18.818 ms/op 16.181 ms/op 1.16
getNodesAtDepth depth 2 x100000 34.900 ms/op 27.725 ms/op 1.26
setNodesAtDepth depth 2 x100000 25.581 ms/op 21.773 ms/op 1.17
tree.getNodesAtDepth - gindexes 10.407 ms/op 9.4025 ms/op 1.11
tree.getNodesAtDepth - push all nodes 3.7741 ms/op 2.8365 ms/op 1.33
tree.getNodesAtDepth - navigation 215.46 us/op 169.30 us/op 1.27
tree.setNodesAtDepth - indexes 673.42 us/op 585.71 us/op 1.15
set at depth 8 1.0550 us/op 732.00 ns/op 1.44
set at depth 16 1.3560 us/op 989.00 ns/op 1.37
set at depth 32 2.1560 us/op 1.6260 us/op 1.33
iterateNodesAtDepth 8 256 28.795 us/op 22.509 us/op 1.28
getNodesAtDepth 8 256 7.2760 us/op 6.0540 us/op 1.20
iterateNodesAtDepth 16 65536 8.2283 ms/op 6.8060 ms/op 1.21
getNodesAtDepth 16 65536 3.1430 ms/op 2.6025 ms/op 1.21
iterateNodesAtDepth 32 250000 30.920 ms/op 25.211 ms/op 1.23
getNodesAtDepth 32 250000 8.9493 ms/op 7.2143 ms/op 1.24
iterateNodesAtDepth 40 250000 31.649 ms/op 25.167 ms/op 1.26
getNodesAtDepth 40 250000 8.8868 ms/op 7.1750 ms/op 1.24
250k validators 14.081 s/op 3.0091 s/op 4.68
bitlist bytes to struct (120,90) 1.2290 us/op 1.3200 us/op 0.93
bitlist bytes to tree (120,90) 4.2360 us/op 5.4550 us/op 0.78
bitlist bytes to struct (2048,2048) 2.0780 us/op 2.2790 us/op 0.91
bitlist bytes to tree (2048,2048) 7.3980 us/op 8.9530 us/op 0.83
ByteListType - deserialize 18.609 ms/op 18.686 ms/op 1.00
BasicListType - deserialize 18.514 ms/op 29.759 ms/op 0.62
ByteListType - serialize 18.537 ms/op 19.034 ms/op 0.97
BasicListType - serialize 23.082 ms/op 22.526 ms/op 1.02
BasicListType - tree_convertToStruct 48.370 ms/op 47.525 ms/op 1.02
List[uint8, 68719476736] len 300000 ViewDU.getAll() + iterate 6.8027 ms/op 5.9649 ms/op 1.14
List[uint8, 68719476736] len 300000 ViewDU.get(i) 7.4885 ms/op 6.3167 ms/op 1.19
Array.push len 300000 empty Array - number 10.859 ms/op 8.6480 ms/op 1.26
Array.set len 300000 from new Array - number 3.1357 ms/op 2.7925 ms/op 1.12
Array.set len 300000 - number 9.5027 ms/op 8.6045 ms/op 1.10
Uint8Array.set len 300000 348.66 us/op 273.31 us/op 1.28
Uint32Array.set len 300000 485.30 us/op 430.77 us/op 1.13
Container({a: uint8, b: uint8}) getViewDU x300000 109.08 ms/op 41.985 ms/op 2.60
ContainerNodeStruct({a: uint8, b: uint8}) getViewDU x300000 22.529 ms/op 13.765 ms/op 1.64
List(Container) len 300000 ViewDU.getAllReadonly() + iterate 679.45 ms/op 401.23 ms/op 1.69
List(Container) len 300000 ViewDU.getAllReadonlyValues() + iterate 524.55 ms/op 499.20 ms/op 1.05
List(Container) len 300000 ViewDU.get(i) 13.906 ms/op 11.972 ms/op 1.16
List(Container) len 300000 ViewDU.getReadonly(i) 12.435 ms/op 11.411 ms/op 1.09
List(ContainerNodeStruct) len 300000 ViewDU.getAllReadonly() + iterate 67.966 ms/op 60.758 ms/op 1.12
List(ContainerNodeStruct) len 300000 ViewDU.getAllReadonlyValues() + iterate 8.2912 ms/op 9.2190 ms/op 0.90
List(ContainerNodeStruct) len 300000 ViewDU.get(i) 11.558 ms/op 10.233 ms/op 1.13
List(ContainerNodeStruct) len 300000 ViewDU.getReadonly(i) 11.638 ms/op 10.316 ms/op 1.13
Array.push len 300000 empty Array - object 10.268 ms/op 8.5220 ms/op 1.20
Array.set len 300000 from new Array - object 3.8324 ms/op 2.8492 ms/op 1.35
Array.set len 300000 - object 10.241 ms/op 8.7091 ms/op 1.18
cachePermanentRootStruct no cache 15.123 us/op 12.767 us/op 1.18
cachePermanentRootStruct with cache 358.00 ns/op 297.00 ns/op 1.21
epochParticipation len 250000 rws 7813 3.9768 ms/op 3.3212 ms/op 1.20
deserialize Attestation - tree 5.4900 us/op 4.4350 us/op 1.24
deserialize Attestation - struct 3.6440 us/op 2.9130 us/op 1.25
deserialize SignedAggregateAndProof - tree 7.0350 us/op 5.7160 us/op 1.23
deserialize SignedAggregateAndProof - struct 5.8380 us/op 4.9550 us/op 1.18
deserialize SyncCommitteeMessage - tree 1.9100 us/op 1.5060 us/op 1.27
deserialize SyncCommitteeMessage - struct 2.2460 us/op 1.7940 us/op 1.25
deserialize SignedContributionAndProof - tree 3.6650 us/op 2.9000 us/op 1.26
deserialize SignedContributionAndProof - struct 5.1110 us/op 4.1330 us/op 1.24
deserialize SignedBeaconBlock - tree 391.38 us/op 325.51 us/op 1.20
deserialize SignedBeaconBlock - struct 262.51 us/op 208.22 us/op 1.26
BeaconState vc 300000 - deserialize tree 1.1738 s/op 1.0681 s/op 1.10
BeaconState vc 300000 - serialize tree 372.29 ms/op 315.85 ms/op 1.18
BeaconState.historicalRoots vc 300000 - deserialize tree 1.3410 us/op 1.1130 us/op 1.20
BeaconState.historicalRoots vc 300000 - serialize tree 1.6640 us/op 1.3020 us/op 1.28
BeaconState.validators vc 300000 - deserialize tree 1.1921 s/op 1.0370 s/op 1.15
BeaconState.validators vc 300000 - serialize tree 315.11 ms/op 265.56 ms/op 1.19
BeaconState.balances vc 300000 - deserialize tree 45.018 ms/op 39.766 ms/op 1.13
BeaconState.balances vc 300000 - serialize tree 4.7537 ms/op 6.6301 ms/op 0.72
BeaconState.previousEpochParticipation vc 300000 - deserialize tree 665.19 us/op 854.13 us/op 0.78
BeaconState.previousEpochParticipation vc 300000 - serialize tree 555.70 us/op 473.26 us/op 1.17
BeaconState.currentEpochParticipation vc 300000 - deserialize tree 660.41 us/op 825.05 us/op 0.80
BeaconState.currentEpochParticipation vc 300000 - serialize tree 549.74 us/op 470.69 us/op 1.17
BeaconState.inactivityScores vc 300000 - deserialize tree 46.729 ms/op 42.619 ms/op 1.10
BeaconState.inactivityScores vc 300000 - serialize tree 6.1068 ms/op 7.1394 ms/op 0.86
hashTreeRoot Attestation - struct 46.368 us/op 45.817 us/op 1.01
hashTreeRoot Attestation - tree 30.963 us/op 25.088 us/op 1.23
hashTreeRoot SignedAggregateAndProof - struct 74.944 us/op 61.010 us/op 1.23
hashTreeRoot SignedAggregateAndProof - tree 42.662 us/op 38.097 us/op 1.12
hashTreeRoot SyncCommitteeMessage - struct 15.266 us/op 15.127 us/op 1.01
hashTreeRoot SyncCommitteeMessage - tree 9.6940 us/op 8.2870 us/op 1.17
hashTreeRoot SignedContributionAndProof - struct 43.251 us/op 43.996 us/op 0.98
hashTreeRoot SignedContributionAndProof - tree 30.712 us/op 30.016 us/op 1.02
hashTreeRoot SignedBeaconBlock - struct 3.8152 ms/op 3.6727 ms/op 1.04
hashTreeRoot SignedBeaconBlock - tree 2.5392 ms/op 2.2069 ms/op 1.15
hashTreeRoot Validator - struct 20.884 us/op 18.962 us/op 1.10
hashTreeRoot Validator - tree 16.889 us/op 15.724 us/op 1.07
BeaconState vc 300000 - hashTreeRoot tree 5.6748 s/op 5.0689 s/op 1.12
BeaconState.historicalRoots vc 300000 - hashTreeRoot tree 2.2190 us/op 1.9410 us/op 1.14
BeaconState.validators vc 300000 - hashTreeRoot tree 5.4600 s/op 4.6978 s/op 1.16
BeaconState.balances vc 300000 - hashTreeRoot tree 144.56 ms/op 124.64 ms/op 1.16
BeaconState.previousEpochParticipation vc 300000 - hashTreeRoot tree 13.878 ms/op 11.949 ms/op 1.16
BeaconState.currentEpochParticipation vc 300000 - hashTreeRoot tree 13.879 ms/op 11.949 ms/op 1.16
BeaconState.inactivityScores vc 300000 - hashTreeRoot tree 141.72 ms/op 110.62 ms/op 1.28
hash64 x18 31.215 us/op 25.028 us/op 1.25
hashTwoObjects x18 28.119 us/op 24.031 us/op 1.17
hash64 x1740 2.9550 ms/op 2.3228 ms/op 1.27
hashTwoObjects x1740 2.6461 ms/op 2.2708 ms/op 1.17
hash64 x2700000 4.4480 s/op 3.6109 s/op 1.23
hashTwoObjects x2700000 4.0240 s/op 3.5226 s/op 1.14
get_exitEpoch - ContainerType 584.00 ns/op 519.00 ns/op 1.13
get_exitEpoch - ContainerNodeStructType 477.00 ns/op 419.00 ns/op 1.14
set_exitEpoch - ContainerType 546.00 ns/op 372.00 ns/op 1.47
set_exitEpoch - ContainerNodeStructType 508.00 ns/op 313.00 ns/op 1.62
get_pubkey - ContainerType 1.8390 us/op 1.6230 us/op 1.13
get_pubkey - ContainerNodeStructType 369.00 ns/op 314.00 ns/op 1.18
hashTreeRoot - ContainerType 633.00 ns/op 491.00 ns/op 1.29
hashTreeRoot - ContainerNodeStructType 711.00 ns/op 541.00 ns/op 1.31
createProof - ContainerType 7.7410 us/op 6.6160 us/op 1.17
createProof - ContainerNodeStructType 41.781 us/op 35.031 us/op 1.19
serialize - ContainerType 3.3980 us/op 2.9560 us/op 1.15
serialize - ContainerNodeStructType 2.7810 us/op 2.3770 us/op 1.17
set_exitEpoch_and_hashTreeRoot - ContainerType 6.5930 us/op 5.7620 us/op 1.14
set_exitEpoch_and_hashTreeRoot - ContainerNodeStructType 18.505 us/op 16.008 us/op 1.16
Array - for of 21.707 us/op 12.908 us/op 1.68
Array - for(;;) 19.727 us/op 10.408 us/op 1.90
basicListValue.readonlyValuesArray() 6.4897 ms/op 5.4730 ms/op 1.19
basicListValue.readonlyValuesArray() + loop all 6.6380 ms/op 5.4217 ms/op 1.22
compositeListValue.readonlyValuesArray() 50.276 ms/op 39.937 ms/op 1.26
compositeListValue.readonlyValuesArray() + loop all 38.072 ms/op 34.043 ms/op 1.12
Number64UintType - get balances list 7.9103 ms/op 6.5380 ms/op 1.21
Number64UintType - set balances list 19.783 ms/op 15.554 ms/op 1.27
Number64UintType - get and increase 10 then set 75.665 ms/op 67.332 ms/op 1.12
Number64UintType - increase 10 using applyDelta 32.123 ms/op 25.473 ms/op 1.26
Number64UintType - increase 10 using applyDeltaInBatch 31.199 ms/op 25.797 ms/op 1.21
tree_newTreeFromUint64Deltas 34.126 ms/op 27.101 ms/op 1.26
unsafeUint8ArrayToTree 56.816 ms/op 49.635 ms/op 1.14
bitLength(50) 383.00 ns/op 312.00 ns/op 1.23
bitLengthStr(50) 425.00 ns/op 369.00 ns/op 1.15
bitLength(8000) 353.00 ns/op 314.00 ns/op 1.12
bitLengthStr(8000) 581.00 ns/op 503.00 ns/op 1.16
bitLength(250000) 355.00 ns/op 311.00 ns/op 1.14
bitLengthStr(250000) 713.00 ns/op 601.00 ns/op 1.19
floor - Math.floor (53) 0.83784 ns/op 0.67040 ns/op 1.25
floor - << 0 (53) 0.83847 ns/op 0.66980 ns/op 1.25
floor - Math.floor (512) 0.83766 ns/op 0.67014 ns/op 1.25
floor - << 0 (512) 0.83798 ns/op 0.67022 ns/op 1.25
fnIf(0) 3.3494 ns/op 2.6782 ns/op 1.25
fnSwitch(0) 6.2828 ns/op 5.0208 ns/op 1.25
fnObj(0) 0.83869 ns/op 0.66984 ns/op 1.25
fnArr(0) 0.83871 ns/op 0.67033 ns/op 1.25
fnIf(4) 5.4434 ns/op 4.3513 ns/op 1.25
fnSwitch(4) 6.2781 ns/op 5.0232 ns/op 1.25
fnObj(4) 0.83820 ns/op 0.66991 ns/op 1.25
fnArr(4) 0.83772 ns/op 0.67025 ns/op 1.25
fnIf(9) 8.3698 ns/op 6.6961 ns/op 1.25
fnSwitch(9) 6.2820 ns/op 5.0474 ns/op 1.24
fnObj(9) 0.83775 ns/op 0.67028 ns/op 1.25
fnArr(9) 0.83768 ns/op 0.67003 ns/op 1.25
Container {a,b,vec} - as struct x100000 84.186 us/op 67.415 us/op 1.25
Container {a,b,vec} - as tree x100000 1.0475 ms/op 837.15 us/op 1.25
Container {a,vec,b} - as struct x100000 126.10 us/op 100.89 us/op 1.25
Container {a,vec,b} - as tree x100000 1.1311 ms/op 904.28 us/op 1.25
get 2 props x1000000 - rawObject 419.47 us/op 335.26 us/op 1.25
get 2 props x1000000 - proxy 167.04 ms/op 133.43 ms/op 1.25
get 2 props x1000000 - customObj 419.43 us/op 335.29 us/op 1.25
Simple object binary -> struct 1.1720 us/op 967.00 ns/op 1.21
Simple object binary -> tree_backed 3.4020 us/op 2.7710 us/op 1.23
Simple object struct -> tree_backed 4.5970 us/op 3.7210 us/op 1.24
Simple object tree_backed -> struct 3.6840 us/op 3.0490 us/op 1.21
Simple object struct -> binary 1.7970 us/op 1.5450 us/op 1.16
Simple object tree_backed -> binary 3.0470 us/op 2.6670 us/op 1.14
aggregationBits binary -> struct 1.1250 us/op 899.00 ns/op 1.25
aggregationBits binary -> tree_backed 4.4070 us/op 3.8450 us/op 1.15
aggregationBits struct -> tree_backed 5.2900 us/op 4.6460 us/op 1.14
aggregationBits tree_backed -> struct 2.1630 us/op 1.8700 us/op 1.16
aggregationBits struct -> binary 1.5380 us/op 1.3430 us/op 1.15
aggregationBits tree_backed -> binary 1.9110 us/op 1.6430 us/op 1.16
List(uint8) 100000 binary -> struct 2.4380 ms/op 1.9585 ms/op 1.24
List(uint8) 100000 binary -> tree_backed 181.97 us/op 180.40 us/op 1.01
List(uint8) 100000 struct -> tree_backed 2.5895 ms/op 2.1614 ms/op 1.20
List(uint8) 100000 tree_backed -> struct 1.7991 ms/op 1.5327 ms/op 1.17
List(uint8) 100000 struct -> binary 2.4178 ms/op 1.9625 ms/op 1.23
List(uint8) 100000 tree_backed -> binary 178.68 us/op 143.15 us/op 1.25
List(uint64Number) 100000 binary -> struct 1.9855 ms/op 1.6757 ms/op 1.18
List(uint64Number) 100000 binary -> tree_backed 6.0658 ms/op 5.4463 ms/op 1.11
List(uint64Number) 100000 struct -> tree_backed 8.8600 ms/op 7.8345 ms/op 1.13
List(uint64Number) 100000 tree_backed -> struct 3.8904 ms/op 3.2261 ms/op 1.21
List(uint64Number) 100000 struct -> binary 2.8125 ms/op 2.3359 ms/op 1.20
List(uint64Number) 100000 tree_backed -> binary 1.8790 ms/op 1.6558 ms/op 1.13
List(Uint64Bigint) 100000 binary -> struct 6.6436 ms/op 5.3682 ms/op 1.24
List(Uint64Bigint) 100000 binary -> tree_backed 7.0699 ms/op 6.5940 ms/op 1.07
List(Uint64Bigint) 100000 struct -> tree_backed 10.803 ms/op 9.1130 ms/op 1.19
List(Uint64Bigint) 100000 tree_backed -> struct 8.4745 ms/op 7.7943 ms/op 1.09
List(Uint64Bigint) 100000 struct -> binary 3.6296 ms/op 2.9126 ms/op 1.25
List(Uint64Bigint) 100000 tree_backed -> binary 1.9058 ms/op 1.4354 ms/op 1.33
Vector(Root) 100000 binary -> struct 59.151 ms/op 50.842 ms/op 1.16
Vector(Root) 100000 binary -> tree_backed 67.042 ms/op 52.858 ms/op 1.27
Vector(Root) 100000 struct -> tree_backed 80.697 ms/op 68.960 ms/op 1.17
Vector(Root) 100000 tree_backed -> struct 93.436 ms/op 79.664 ms/op 1.17
Vector(Root) 100000 struct -> binary 4.0710 ms/op 3.1679 ms/op 1.29
Vector(Root) 100000 tree_backed -> binary 17.836 ms/op 14.204 ms/op 1.26
List(Validator) 100000 binary -> struct 234.56 ms/op 202.13 ms/op 1.16
List(Validator) 100000 binary -> tree_backed 582.11 ms/op 517.99 ms/op 1.12
List(Validator) 100000 struct -> tree_backed 665.90 ms/op 553.03 ms/op 1.20
List(Validator) 100000 tree_backed -> struct 384.26 ms/op 322.98 ms/op 1.19
List(Validator) 100000 struct -> binary 62.675 ms/op 46.170 ms/op 1.36
List(Validator) 100000 tree_backed -> binary 167.49 ms/op 135.92 ms/op 1.23
List(Validator-NS) 100000 binary -> struct 243.18 ms/op 203.21 ms/op 1.20
List(Validator-NS) 100000 binary -> tree_backed 328.74 ms/op 282.53 ms/op 1.16
List(Validator-NS) 100000 struct -> tree_backed 408.14 ms/op 343.61 ms/op 1.19
List(Validator-NS) 100000 tree_backed -> struct 341.77 ms/op 283.61 ms/op 1.21
List(Validator-NS) 100000 struct -> binary 60.705 ms/op 46.756 ms/op 1.30
List(Validator-NS) 100000 tree_backed -> binary 67.445 ms/op 55.200 ms/op 1.22
get epochStatuses - MutableVector 146.84 us/op 121.80 us/op 1.21
get epochStatuses - ViewDU 349.14 us/op 281.36 us/op 1.24
set epochStatuses - ListTreeView 2.7260 ms/op 2.3047 ms/op 1.18
set epochStatuses - ListTreeView - set() 802.18 us/op 697.10 us/op 1.15
set epochStatuses - ListTreeView - commit() 764.94 us/op 684.86 us/op 1.12
bitstring 929.97 ns/op 768.48 ns/op 1.21
bit mask 15.985 ns/op 12.804 ns/op 1.25
struct - increase slot to 1000000 2.7334 ms/op 2.1861 ms/op 1.25
UintNumberType - increase slot to 1000000 59.989 ms/op 51.591 ms/op 1.16
UintBigintType - increase slot to 1000000 744.07 ms/op 617.89 ms/op 1.20
UintBigint8 x 100000 tree_deserialize 7.7961 ms/op 6.2157 ms/op 1.25
UintBigint8 x 100000 tree_serialize 2.5445 ms/op 2.2040 ms/op 1.15
UintBigint16 x 100000 tree_deserialize 7.1453 ms/op 5.7350 ms/op 1.25
UintBigint16 x 100000 tree_serialize 2.6650 ms/op 2.1539 ms/op 1.24
UintBigint32 x 100000 tree_deserialize 9.1534 ms/op 7.5000 ms/op 1.22
UintBigint32 x 100000 tree_serialize 2.3676 ms/op 1.9421 ms/op 1.22
UintBigint64 x 100000 tree_deserialize 10.128 ms/op 8.0087 ms/op 1.26
UintBigint64 x 100000 tree_serialize 3.1751 ms/op 2.5548 ms/op 1.24
UintBigint8 x 100000 value_deserialize 1.0890 ms/op 870.87 us/op 1.25
UintBigint8 x 100000 value_serialize 1.4325 ms/op 1.3027 ms/op 1.10
UintBigint16 x 100000 value_deserialize 1.1682 ms/op 933.71 us/op 1.25
UintBigint16 x 100000 value_serialize 1.5668 ms/op 1.4075 ms/op 1.11
UintBigint32 x 100000 value_deserialize 1.0538 ms/op 852.20 us/op 1.24
UintBigint32 x 100000 value_serialize 1.5997 ms/op 1.4149 ms/op 1.13
UintBigint64 x 100000 value_deserialize 1.1456 ms/op 905.17 us/op 1.27
UintBigint64 x 100000 value_serialize 1.8242 ms/op 1.5883 ms/op 1.15
UintBigint8 x 100000 deserialize 8.4333 ms/op 6.8015 ms/op 1.24
UintBigint8 x 100000 serialize 3.1745 ms/op 2.5287 ms/op 1.26
UintBigint16 x 100000 deserialize 9.2119 ms/op 7.1703 ms/op 1.28
UintBigint16 x 100000 serialize 3.4067 ms/op 2.5192 ms/op 1.35
UintBigint32 x 100000 deserialize 10.267 ms/op 8.1715 ms/op 1.26
UintBigint32 x 100000 serialize 5.8928 ms/op 4.3966 ms/op 1.34
UintBigint64 x 100000 deserialize 6.4123 ms/op 5.4941 ms/op 1.17
UintBigint64 x 100000 serialize 3.0528 ms/op 2.5368 ms/op 1.20
UintBigint128 x 100000 deserialize 10.515 ms/op 8.3336 ms/op 1.26
UintBigint128 x 100000 serialize 36.636 ms/op 27.551 ms/op 1.33
UintBigint256 x 100000 deserialize 20.312 ms/op 15.755 ms/op 1.29
UintBigint256 x 100000 serialize 105.27 ms/op 83.136 ms/op 1.27
Slice from Uint8Array x25000 1.8917 ms/op 1.8364 ms/op 1.03
Slice from ArrayBuffer x25000 33.084 ms/op 30.036 ms/op 1.10
Slice from ArrayBuffer x25000 + new Uint8Array 35.104 ms/op 33.473 ms/op 1.05
Copy Uint8Array 100000 iterate 1.8234 ms/op 1.4873 ms/op 1.23
Copy Uint8Array 100000 slice 133.31 us/op 158.04 us/op 0.84
Copy Uint8Array 100000 Uint8Array.prototype.slice.call 132.43 us/op 149.68 us/op 0.88
Copy Buffer 100000 Uint8Array.prototype.slice.call 131.86 us/op 154.83 us/op 0.85
Copy Uint8Array 100000 slice + set 356.18 us/op 342.01 us/op 1.04
Copy Uint8Array 100000 subarray + set 141.17 us/op 148.83 us/op 0.95
Copy Uint8Array 100000 slice arrayBuffer 163.92 us/op 155.18 us/op 1.06
Uint64 deserialize 100000 - iterate Uint8Array 2.7458 ms/op 2.3467 ms/op 1.17
Uint64 deserialize 100000 - by Uint32A 2.5624 ms/op 2.2267 ms/op 1.15
Uint64 deserialize 100000 - by DataView.getUint32 x2 2.5109 ms/op 2.3098 ms/op 1.09
Uint64 deserialize 100000 - by DataView.getBigUint64 8.5417 ms/op 7.0624 ms/op 1.21
Uint64 deserialize 100000 - by byte 88.121 ms/op 69.229 ms/op 1.27

by benchmarkbot/action

Copy link
Contributor

@g11tech g11tech left a comment

Choose a reason for hiding this comment

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

looks amazing to me, leaving it unapproved if there is a followup on the perf improvement

@@ -81,6 +81,9 @@ module.exports = {

// Prevents accidentally pushing a commit with .only in Mocha tests
"no-only-tests/no-only-tests": "error",

// TEMP Disabled while eslint-plugin-import support ESM (Typescript does support it) https://github.com/import-js/eslint-plugin-import/issues/2170
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

No these lines were just copy pastad from lodestar's eslintrc

@wemeetagain wemeetagain changed the title Add swappable hasher, default to noble-hashes feat: add swappable hasher, default to noble-hashes Mar 27, 2023
@paulmillr
Copy link

I wonder why the perf difference here is 5x, while noble-hashes benchmarks only show 1.5x on 64b. Are you confident the benchmarks are proper?

@wemeetagain
Copy link
Member Author

I wonder why the perf difference here is 5x, while noble-hashes benchmarks only show 1.5x on 64b. Are you confident the benchmarks are proper?

We mostly hash two HashObjects, which is 3.5x. Not quite to 5x but in the ballpark.

@dapplion
Copy link
Contributor

@wemeetagain can you set the benchmarks to use the WASM version? Else we go blind for Lodestar performance tracking

@dapplion
Copy link
Contributor

Thanks @wemeetagain benchmarks look like before now 👍

@paulmillr
Copy link

Could you merge this please? Current wasm breaks unsupported environments.

@wemeetagain
Copy link
Member Author

Could you merge this please?

Yes, looking for a ✔️ from @ChainSafe/lodestar and will cut a release afterwards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants