ssz
ssz copied to clipboard
feat: getAll() apis to support output parameters
Motivation
- right now at lodestar, it has to allocate new array to loop through all elements and it cost memory allocation
- for readonly operation, ssz still have to recompute root, see #379
Description
- improve getAll() apis by supporting output parameters
- add
forEach()apis - if a ViewDU does not change root node after a commit(), its parent should discard the change and so that it does not have to recompute root
Closes #379
Performance Report
✔️ no performance regression detected
Full benchmark results
| Benchmark suite | Current: 1d786f3e1e0cca51f671aa1e4f3e7b4ba47a364b | Previous: cf3e1f038c8bf7cba1bb27c38540e50b0391d0e6 | Ratio |
|---|---|---|---|
| digestTwoHashObjects 50023 times | 47.970 ms/op | 47.711 ms/op | 1.01 |
| digest64 50023 times | 54.543 ms/op | 53.527 ms/op | 1.02 |
| digest 50023 times | 56.163 ms/op | 54.509 ms/op | 1.03 |
| input length 32 | 1.2770 us/op | 1.2080 us/op | 1.06 |
| input length 64 | 1.3810 us/op | 1.3330 us/op | 1.04 |
| input length 128 | 2.4140 us/op | 2.3010 us/op | 1.05 |
| input length 256 | 3.5010 us/op | 3.4310 us/op | 1.02 |
| input length 512 | 5.6740 us/op | 5.6630 us/op | 1.00 |
| input length 1024 | 10.795 us/op | 10.983 us/op | 0.98 |
| digest 1000000 times | 934.85 ms/op | 873.36 ms/op | 1.07 |
| hashObjectToByteArray 50023 times | 1.4315 ms/op | 1.4322 ms/op | 1.00 |
| byteArrayToHashObject 50023 times | 2.1788 ms/op | 2.4755 ms/op | 0.88 |
| digest64 200092 times | 231.09 ms/op | 218.28 ms/op | 1.06 |
| hash 200092 times using batchHash4UintArray64s | 240.69 ms/op | 237.10 ms/op | 1.02 |
| digest64HashObjects 200092 times | 199.06 ms/op | 194.39 ms/op | 1.02 |
| hash 200092 times using batchHash4HashObjectInputs | 211.98 ms/op | 200.14 ms/op | 1.06 |
| getGindicesAtDepth | 4.3540 us/op | 4.2930 us/op | 1.01 |
| iterateAtDepth | 7.8430 us/op | 7.7060 us/op | 1.02 |
| getGindexBits | 475.00 ns/op | 461.00 ns/op | 1.03 |
| gindexIterator | 1.0790 us/op | 1.0770 us/op | 1.00 |
| HashComputationLevel.push then loop | 25.914 ms/op | 25.300 ms/op | 1.02 |
| HashComputation[] push then loop | 49.713 ms/op | 48.617 ms/op | 1.02 |
| hash 2 Uint8Array 500000 times - as-sha256 | 546.96 ms/op | 538.29 ms/op | 1.02 |
| hashTwoObjects 500000 times - as-sha256 | 520.17 ms/op | 508.02 ms/op | 1.02 |
| executeHashComputations - as-sha256 | 49.672 ms/op | 45.516 ms/op | 1.09 |
| hash 2 Uint8Array 500000 times - noble | 1.1109 s/op | 1.0725 s/op | 1.04 |
| hashTwoObjects 500000 times - noble | 1.5967 s/op | 1.5023 s/op | 1.06 |
| executeHashComputations - noble | 41.106 ms/op | 36.074 ms/op | 1.14 |
| hash 2 Uint8Array 500000 times - hashtree | 226.96 ms/op | 254.38 ms/op | 0.89 |
| hashTwoObjects 500000 times - hashtree | 231.33 ms/op | 285.98 ms/op | 0.81 |
| executeHashComputations - hashtree | 10.262 ms/op | 11.598 ms/op | 0.88 |
| getHashComputations | 2.7371 ms/op | 2.7371 ms/op | 1.00 |
| executeHashComputations | 12.627 ms/op | 11.964 ms/op | 1.06 |
| get root | 18.088 ms/op | 17.848 ms/op | 1.01 |
| getNodeH() x7812.5 avg hindex | 12.994 us/op | 12.154 us/op | 1.07 |
| getNodeH() x7812.5 index 0 | 6.2940 us/op | 6.2600 us/op | 1.01 |
| getNodeH() x7812.5 index 7 | 6.2730 us/op | 6.2270 us/op | 1.01 |
| getNodeH() x7812.5 index 7 with key array | 6.2410 us/op | 6.2540 us/op | 1.00 |
| new LeafNode() x7812.5 | 14.678 us/op | 14.663 us/op | 1.00 |
| getHashComputations 250000 nodes | 19.639 ms/op | 19.524 ms/op | 1.01 |
| batchHash 250000 nodes | 104.28 ms/op | 85.990 ms/op | 1.21 |
| get root 250000 nodes | 122.76 ms/op | 119.77 ms/op | 1.03 |
| getHashComputations 500000 nodes | 28.244 ms/op | 26.630 ms/op | 1.06 |
| batchHash 500000 nodes | 179.76 ms/op | 153.23 ms/op | 1.17 |
| get root 500000 nodes | 245.89 ms/op | 243.45 ms/op | 1.01 |
| getHashComputations 1000000 nodes | 89.574 ms/op | 56.644 ms/op | 1.58 |
| batchHash 1000000 nodes | 390.57 ms/op | 326.79 ms/op | 1.20 |
| get root 1000000 nodes | 500.92 ms/op | 491.85 ms/op | 1.02 |
| multiproof - depth 15, 1 requested leaves | 8.6070 us/op | 8.5500 us/op | 1.01 |
| tree offset multiproof - depth 15, 1 requested leaves | 18.885 us/op | 18.626 us/op | 1.01 |
| compact multiproof - depth 15, 1 requested leaves | 3.7910 us/op | 3.5070 us/op | 1.08 |
| multiproof - depth 15, 2 requested leaves | 12.068 us/op | 12.237 us/op | 0.99 |
| tree offset multiproof - depth 15, 2 requested leaves | 22.708 us/op | 22.648 us/op | 1.00 |
| compact multiproof - depth 15, 2 requested leaves | 3.7150 us/op | 3.5100 us/op | 1.06 |
| multiproof - depth 15, 3 requested leaves | 16.494 us/op | 16.920 us/op | 0.97 |
| tree offset multiproof - depth 15, 3 requested leaves | 28.873 us/op | 28.126 us/op | 1.03 |
| compact multiproof - depth 15, 3 requested leaves | 4.6220 us/op | 4.2140 us/op | 1.10 |
| multiproof - depth 15, 4 requested leaves | 21.753 us/op | 23.081 us/op | 0.94 |
| tree offset multiproof - depth 15, 4 requested leaves | 35.438 us/op | 35.934 us/op | 0.99 |
| compact multiproof - depth 15, 4 requested leaves | 5.2650 us/op | 5.1210 us/op | 1.03 |
| packedRootsBytesToLeafNodes bytes 4000 offset 0 | 1.8910 us/op | 2.0670 us/op | 0.91 |
| packedRootsBytesToLeafNodes bytes 4000 offset 1 | 1.8210 us/op | 1.9540 us/op | 0.93 |
| packedRootsBytesToLeafNodes bytes 4000 offset 2 | 1.8370 us/op | 1.9530 us/op | 0.94 |
| packedRootsBytesToLeafNodes bytes 4000 offset 3 | 1.8180 us/op | 1.9540 us/op | 0.93 |
| subtreeFillToContents depth 40 count 250000 | 42.956 ms/op | 44.977 ms/op | 0.96 |
| setRoot - gindexBitstring | 10.777 ms/op | 9.6980 ms/op | 1.11 |
| setRoot - gindex | 11.491 ms/op | 9.5255 ms/op | 1.21 |
| getRoot - gindexBitstring | 2.7057 ms/op | 2.5691 ms/op | 1.05 |
| getRoot - gindex | 3.3373 ms/op | 3.2999 ms/op | 1.01 |
| getHashObject then setHashObject | 12.616 ms/op | 9.6613 ms/op | 1.31 |
| setNodeWithFn | 9.7999 ms/op | 7.8990 ms/op | 1.24 |
| getNodeAtDepth depth 0 x100000 | 1.1146 ms/op | 1.1146 ms/op | 1.00 |
| setNodeAtDepth depth 0 x100000 | 3.1402 ms/op | 2.4467 ms/op | 1.28 |
| getNodesAtDepth depth 0 x100000 | 1.0547 ms/op | 1.0529 ms/op | 1.00 |
| setNodesAtDepth depth 0 x100000 | 1.5158 ms/op | 1.5160 ms/op | 1.00 |
| getNodeAtDepth depth 1 x100000 | 1.1848 ms/op | 1.1842 ms/op | 1.00 |
| setNodeAtDepth depth 1 x100000 | 6.7950 ms/op | 5.2486 ms/op | 1.29 |
| getNodesAtDepth depth 1 x100000 | 1.1780 ms/op | 1.1809 ms/op | 1.00 |
| setNodesAtDepth depth 1 x100000 | 5.4551 ms/op | 4.4512 ms/op | 1.23 |
| getNodeAtDepth depth 2 x100000 | 1.4536 ms/op | 1.4532 ms/op | 1.00 |
| setNodeAtDepth depth 2 x100000 | 10.397 ms/op | 12.918 ms/op | 0.80 |
| getNodesAtDepth depth 2 x100000 | 20.932 ms/op | 18.310 ms/op | 1.14 |
| setNodesAtDepth depth 2 x100000 | 18.251 ms/op | 13.076 ms/op | 1.40 |
| tree.getNodesAtDepth - gindexes | 9.5926 ms/op | 7.5604 ms/op | 1.27 |
| tree.getNodesAtDepth - push all nodes | 2.4597 ms/op | 1.9187 ms/op | 1.28 |
| tree.getNodesAtDepth - navigation | 232.28 us/op | 233.69 us/op | 0.99 |
| tree.setNodesAtDepth - indexes | 484.68 us/op | 419.24 us/op | 1.16 |
| set at depth 8 | 559.00 ns/op | 457.00 ns/op | 1.22 |
| set at depth 16 | 728.00 ns/op | 594.00 ns/op | 1.23 |
| set at depth 32 | 1.1320 us/op | 935.00 ns/op | 1.21 |
| iterateNodesAtDepth 8 256 | 15.082 us/op | 13.176 us/op | 1.14 |
| getNodesAtDepth 8 256 | 3.7780 us/op | 3.3530 us/op | 1.13 |
| iterateNodesAtDepth 16 65536 | 5.1072 ms/op | 4.1844 ms/op | 1.22 |
| getNodesAtDepth 16 65536 | 1.5558 ms/op | 1.5705 ms/op | 0.99 |
| iterateNodesAtDepth 32 250000 | 16.002 ms/op | 15.211 ms/op | 1.05 |
| getNodesAtDepth 32 250000 | 4.3069 ms/op | 4.3382 ms/op | 0.99 |
| iterateNodesAtDepth 40 250000 | 16.006 ms/op | 15.110 ms/op | 1.06 |
| getNodesAtDepth 40 250000 | 4.3140 ms/op | 4.3206 ms/op | 1.00 |
| 250000 validators root getter | 125.63 ms/op | 120.59 ms/op | 1.04 |
| 250000 validators batchHash() | 127.05 ms/op | 80.707 ms/op | 1.57 |
| 250000 validators hashComputations | 16.406 ms/op | 13.403 ms/op | 1.22 |
| bitlist bytes to struct (120,90) | 948.00 ns/op | 964.00 ns/op | 0.98 |
| bitlist bytes to tree (120,90) | 3.5820 us/op | 3.6930 us/op | 0.97 |
| bitlist bytes to struct (2048,2048) | 1.3100 us/op | 1.3410 us/op | 0.98 |
| bitlist bytes to tree (2048,2048) | 4.0990 us/op | 4.3120 us/op | 0.95 |
| ByteListType - deserialize | 8.2741 ms/op | 8.0872 ms/op | 1.02 |
| BasicListType |
16.941 ms/op | 17.501 ms/op | 0.97 |
| ByteListType - serialize | 7.7145 ms/op | 7.6720 ms/op | 1.01 |
| BasicListType |
10.711 ms/op | 12.735 ms/op | 0.84 |
| BasicListType |
28.574 ms/op | 29.663 ms/op | 0.96 |
| List[uint8, 68719476736] len 300000 ViewDU.getAll() + iterate | 4.6423 ms/op | 4.8328 ms/op | 0.96 |
| List[uint8, 68719476736] len 300000 ViewDU.get(i) | 4.0018 ms/op | 3.9799 ms/op | 1.01 |
| Array.push len 300000 empty Array - number | 6.4981 ms/op | 7.1715 ms/op | 0.91 |
| Array.set len 300000 from new Array - number | 2.1399 ms/op | 2.2612 ms/op | 0.95 |
| Array.set len 300000 - number | 6.7129 ms/op | 5.9269 ms/op | 1.13 |
| Uint8Array.set len 300000 | 376.51 us/op | 539.23 us/op | 0.70 |
| Uint32Array.set len 300000 | 447.25 us/op | 458.65 us/op | 0.98 |
| Container({a: uint8, b: uint8}) getViewDU x300000 | 48.886 ms/op | 49.126 ms/op | 1.00 |
| ContainerNodeStruct({a: uint8, b: uint8}) getViewDU x300000 | 11.209 ms/op | 10.768 ms/op | 1.04 |
| List(Container) len 300000 ViewDU.getAllReadonly() + iterate | 214.56 ms/op | 214.74 ms/op | 1.00 |
| List(Container) len 300000 ViewDU.getAllReadonlyValues() + iterate | 282.59 ms/op | 256.68 ms/op | 1.10 |
| List(Container) len 300000 ViewDU.get(i) | 6.9594 ms/op | 6.8412 ms/op | 1.02 |
| List(Container) len 300000 ViewDU.getReadonly(i) | 6.2368 ms/op | 6.3793 ms/op | 0.98 |
| List(ContainerNodeStruct) len 300000 ViewDU.getAllReadonly() + iterate | 38.221 ms/op | 38.327 ms/op | 1.00 |
| List(ContainerNodeStruct) len 300000 ViewDU.getAllReadonlyValues() + iterate | 5.1657 ms/op | 5.0546 ms/op | 1.02 |
| List(ContainerNodeStruct) len 300000 ViewDU.get(i) | 6.0341 ms/op | 5.9697 ms/op | 1.01 |
| List(ContainerNodeStruct) len 300000 ViewDU.getReadonly(i) | 5.9501 ms/op | 5.9126 ms/op | 1.01 |
| Array.push len 300000 empty Array - object | 5.9377 ms/op | 5.9100 ms/op | 1.00 |
| Array.set len 300000 from new Array - object | 2.0513 ms/op | 1.9903 ms/op | 1.03 |
| Array.set len 300000 - object | 5.9754 ms/op | 5.9399 ms/op | 1.01 |
| cachePermanentRootStruct no cache | 5.1760 us/op | 5.8350 us/op | 0.89 |
| cachePermanentRootStruct with cache | 231.00 ns/op | 202.00 ns/op | 1.14 |
| epochParticipation len 250000 rws 7813 | 2.1666 ms/op | 2.2079 ms/op | 0.98 |
| BeaconState ViewDU hashTreeRoot() vc=200000 | 107.10 ms/op | 104.39 ms/op | 1.03 |
| BeaconState ViewDU recursive hash - commit step vc=200000 | 4.2641 ms/op | 4.3694 ms/op | 0.98 |
| BeaconState ViewDU validator tree creation vc=10000 | 36.326 ms/op | 34.769 ms/op | 1.04 |
| BeaconState ViewDU batchHashTreeRoot vc=200000 | 101.02 ms/op | 95.448 ms/op | 1.06 |
| BeaconState ViewDU hashTreeRoot - commit step vc=200000 | 86.581 ms/op | 84.812 ms/op | 1.02 |
| BeaconState ViewDU hashTreeRoot - hash step vc=200000 | 17.592 ms/op | 15.164 ms/op | 1.16 |
| deserialize Attestation - tree | 4.7250 us/op | 4.0550 us/op | 1.17 |
| deserialize Attestation - struct | 2.0330 us/op | 1.9280 us/op | 1.05 |
| deserialize SignedAggregateAndProof - tree | 3.8990 us/op | 3.8610 us/op | 1.01 |
| deserialize SignedAggregateAndProof - struct | 3.3280 us/op | 2.9710 us/op | 1.12 |
| deserialize SyncCommitteeMessage - tree | 1.2080 us/op | 1.0570 us/op | 1.14 |
| deserialize SyncCommitteeMessage - struct | 1.3120 us/op | 1.0560 us/op | 1.24 |
| deserialize SignedContributionAndProof - tree | 2.2570 us/op | 2.1000 us/op | 1.07 |
| deserialize SignedContributionAndProof - struct | 2.4830 us/op | 2.2570 us/op | 1.10 |
| deserialize SignedBeaconBlock - tree | 226.99 us/op | 208.21 us/op | 1.09 |
| deserialize SignedBeaconBlock - struct | 151.14 us/op | 120.44 us/op | 1.25 |
| BeaconState vc 300000 - deserialize tree | 641.96 ms/op | 639.02 ms/op | 1.00 |
| BeaconState vc 300000 - serialize tree | 168.49 ms/op | 106.89 ms/op | 1.58 |
| BeaconState.historicalRoots vc 300000 - deserialize tree | 737.00 ns/op | 856.00 ns/op | 0.86 |
| BeaconState.historicalRoots vc 300000 - serialize tree | 734.00 ns/op | 683.00 ns/op | 1.07 |
| BeaconState.validators vc 300000 - deserialize tree | 601.54 ms/op | 577.60 ms/op | 1.04 |
| BeaconState.validators vc 300000 - serialize tree | 101.18 ms/op | 102.90 ms/op | 0.98 |
| BeaconState.balances vc 300000 - deserialize tree | 24.358 ms/op | 20.857 ms/op | 1.17 |
| BeaconState.balances vc 300000 - serialize tree | 3.5123 ms/op | 3.5011 ms/op | 1.00 |
| BeaconState.previousEpochParticipation vc 300000 - deserialize tree | 398.45 us/op | 373.72 us/op | 1.07 |
| BeaconState.previousEpochParticipation vc 300000 - serialize tree | 277.49 us/op | 280.74 us/op | 0.99 |
| BeaconState.currentEpochParticipation vc 300000 - deserialize tree | 435.10 us/op | 372.14 us/op | 1.17 |
| BeaconState.currentEpochParticipation vc 300000 - serialize tree | 276.82 us/op | 276.97 us/op | 1.00 |
| BeaconState.inactivityScores vc 300000 - deserialize tree | 16.998 ms/op | 23.779 ms/op | 0.71 |
| BeaconState.inactivityScores vc 300000 - serialize tree | 4.3829 ms/op | 3.5118 ms/op | 1.25 |
| hashTreeRoot Attestation - struct | 23.564 us/op | 20.644 us/op | 1.14 |
| hashTreeRoot Attestation - tree | 9.1400 us/op | 9.3950 us/op | 0.97 |
| hashTreeRoot SignedAggregateAndProof - struct | 27.171 us/op | 31.939 us/op | 0.85 |
| hashTreeRoot SignedAggregateAndProof - tree | 13.410 us/op | 13.052 us/op | 1.03 |
| hashTreeRoot SyncCommitteeMessage - struct | 7.0530 us/op | 6.7600 us/op | 1.04 |
| hashTreeRoot SyncCommitteeMessage - tree | 3.4320 us/op | 3.3160 us/op | 1.03 |
| hashTreeRoot SignedContributionAndProof - struct | 16.458 us/op | 17.317 us/op | 0.95 |
| hashTreeRoot SignedContributionAndProof - tree | 9.3030 us/op | 9.0480 us/op | 1.03 |
| hashTreeRoot SignedBeaconBlock - struct | 1.4010 ms/op | 1.5513 ms/op | 0.90 |
| hashTreeRoot SignedBeaconBlock - tree | 809.75 us/op | 793.26 us/op | 1.02 |
| hashTreeRoot Validator - struct | 9.9300 us/op | 9.4330 us/op | 1.05 |
| hashTreeRoot Validator - tree | 8.3840 us/op | 7.1940 us/op | 1.17 |
| BeaconState vc 300000 - hashTreeRoot tree | 2.2894 s/op | 2.1274 s/op | 1.08 |
| BeaconState vc 300000 - batchHashTreeRoot tree | 3.5756 s/op | 3.4219 s/op | 1.04 |
| BeaconState.historicalRoots vc 300000 - hashTreeRoot tree | 1.0160 us/op | 988.00 ns/op | 1.03 |
| BeaconState.validators vc 300000 - hashTreeRoot tree | 2.1680 s/op | 2.1387 s/op | 1.01 |
| BeaconState.balances vc 300000 - hashTreeRoot tree | 35.299 ms/op | 33.181 ms/op | 1.06 |
| BeaconState.previousEpochParticipation vc 300000 - hashTreeRoot tree | 4.5251 ms/op | 4.0860 ms/op | 1.11 |
| BeaconState.currentEpochParticipation vc 300000 - hashTreeRoot tree | 4.3410 ms/op | 4.0867 ms/op | 1.06 |
| BeaconState.inactivityScores vc 300000 - hashTreeRoot tree | 36.170 ms/op | 33.022 ms/op | 1.10 |
| hash64 x18 | 8.9800 us/op | 11.957 us/op | 0.75 |
| hashTwoObjects x18 | 9.0820 us/op | 12.337 us/op | 0.74 |
| hash64 x1740 | 841.67 us/op | 1.0911 ms/op | 0.77 |
| hashTwoObjects x1740 | 845.39 us/op | 1.1583 ms/op | 0.73 |
| hash64 x2700000 | 1.3107 s/op | 1.6925 s/op | 0.77 |
| hashTwoObjects x2700000 | 1.3299 s/op | 1.8197 s/op | 0.73 |
| get_exitEpoch - ContainerType | 405.00 ns/op | 618.00 ns/op | 0.66 |
| get_exitEpoch - ContainerNodeStructType | 430.00 ns/op | 622.00 ns/op | 0.69 |
| set_exitEpoch - ContainerType | 432.00 ns/op | 641.00 ns/op | 0.67 |
| set_exitEpoch - ContainerNodeStructType | 418.00 ns/op | 635.00 ns/op | 0.66 |
| get_pubkey - ContainerType | 976.00 ns/op | 2.1500 us/op | 0.45 |
| get_pubkey - ContainerNodeStructType | 410.00 ns/op | 603.00 ns/op | 0.68 |
| hashTreeRoot - ContainerType | 675.00 ns/op | 1.0140 us/op | 0.67 |
| hashTreeRoot - ContainerNodeStructType | 713.00 ns/op | 1.0550 us/op | 0.68 |
| createProof - ContainerType | 6.9150 us/op | 7.2030 us/op | 0.96 |
| createProof - ContainerNodeStructType | 27.207 us/op | 32.369 us/op | 0.84 |
| serialize - ContainerType | 2.1310 us/op | 2.2660 us/op | 0.94 |
| serialize - ContainerNodeStructType | 1.6120 us/op | 1.6740 us/op | 0.96 |
| set_exitEpoch_and_hashTreeRoot - ContainerType | 2.8330 us/op | 3.1040 us/op | 0.91 |
| set_exitEpoch_and_hashTreeRoot - ContainerNodeStructType | 7.6980 us/op | 7.6240 us/op | 1.01 |
| Array - for of | 5.8100 us/op | 5.6620 us/op | 1.03 |
| Array - for(;;) | 5.7670 us/op | 5.7570 us/op | 1.00 |
| basicListValue.readonlyValuesArray() | 4.3710 ms/op | 4.5532 ms/op | 0.96 |
| basicListValue.readonlyValuesArray() + loop all | 4.8021 ms/op | 4.6071 ms/op | 1.04 |
| compositeListValue.readonlyValuesArray() | 29.709 ms/op | 27.373 ms/op | 1.09 |
| compositeListValue.readonlyValuesArray() + loop all | 29.311 ms/op | 27.646 ms/op | 1.06 |
| Number64UintType - get balances list | 4.1102 ms/op | 4.1377 ms/op | 0.99 |
| Number64UintType - set balances list | 10.032 ms/op | 9.9409 ms/op | 1.01 |
| Number64UintType - get and increase 10 then set | 39.622 ms/op | 40.810 ms/op | 0.97 |
| Number64UintType - increase 10 using applyDelta | 16.420 ms/op | 15.926 ms/op | 1.03 |
| Number64UintType - increase 10 using applyDeltaInBatch | 16.469 ms/op | 15.997 ms/op | 1.03 |
| tree_newTreeFromUint64Deltas | 17.415 ms/op | 17.334 ms/op | 1.00 |
| unsafeUint8ArrayToTree | 31.500 ms/op | 32.137 ms/op | 0.98 |
| bitLength(50) | 219.00 ns/op | 232.00 ns/op | 0.94 |
| bitLengthStr(50) | 200.00 ns/op | 222.00 ns/op | 0.90 |
| bitLength(8000) | 211.00 ns/op | 219.00 ns/op | 0.96 |
| bitLengthStr(8000) | 250.00 ns/op | 262.00 ns/op | 0.95 |
| bitLength(250000) | 206.00 ns/op | 219.00 ns/op | 0.94 |
| bitLengthStr(250000) | 276.00 ns/op | 300.00 ns/op | 0.92 |
| floor - Math.floor (53) | 1.2372 ns/op | 1.2370 ns/op | 1.00 |
| floor - << 0 (53) | 1.2378 ns/op | 1.2398 ns/op | 1.00 |
| floor - Math.floor (512) | 1.2539 ns/op | 1.2368 ns/op | 1.01 |
| floor - << 0 (512) | 1.2374 ns/op | 1.2369 ns/op | 1.00 |
| fnIf(0) | 1.5892 ns/op | 1.5519 ns/op | 1.02 |
| fnSwitch(0) | 2.1650 ns/op | 2.1646 ns/op | 1.00 |
| fnObj(0) | 1.5468 ns/op | 1.5477 ns/op | 1.00 |
| fnArr(0) | 1.5476 ns/op | 1.5472 ns/op | 1.00 |
| fnIf(4) | 2.1650 ns/op | 2.1718 ns/op | 1.00 |
| fnSwitch(4) | 2.1664 ns/op | 2.2115 ns/op | 0.98 |
| fnObj(4) | 1.5514 ns/op | 1.5479 ns/op | 1.00 |
| fnArr(4) | 1.5697 ns/op | 1.5544 ns/op | 1.01 |
| fnIf(9) | 3.0936 ns/op | 3.0913 ns/op | 1.00 |
| fnSwitch(9) | 2.1974 ns/op | 2.1645 ns/op | 1.02 |
| fnObj(9) | 1.5460 ns/op | 1.5515 ns/op | 1.00 |
| fnArr(9) | 1.5471 ns/op | 1.5495 ns/op | 1.00 |
| Container {a,b,vec} - as struct x100000 | 123.91 us/op | 123.83 us/op | 1.00 |
| Container {a,b,vec} - as tree x100000 | 342.10 us/op | 340.48 us/op | 1.00 |
| Container {a,vec,b} - as struct x100000 | 154.77 us/op | 155.27 us/op | 1.00 |
| Container {a,vec,b} - as tree x100000 | 371.45 us/op | 376.95 us/op | 0.99 |
| get 2 props x1000000 - rawObject | 311.26 us/op | 309.74 us/op | 1.00 |
| get 2 props x1000000 - proxy | 72.738 ms/op | 73.814 ms/op | 0.99 |
| get 2 props x1000000 - customObj | 309.47 us/op | 309.40 us/op | 1.00 |
| Simple object binary -> struct | 821.00 ns/op | 843.00 ns/op | 0.97 |
| Simple object binary -> tree_backed | 1.7130 us/op | 1.7310 us/op | 0.99 |
| Simple object struct -> tree_backed | 2.4920 us/op | 2.4210 us/op | 1.03 |
| Simple object tree_backed -> struct | 1.9080 us/op | 2.3100 us/op | 0.83 |
| Simple object struct -> binary | 958.00 ns/op | 1.1690 us/op | 0.82 |
| Simple object tree_backed -> binary | 1.5930 us/op | 1.6010 us/op | 1.00 |
| aggregationBits binary -> struct | 603.00 ns/op | 616.00 ns/op | 0.98 |
| aggregationBits binary -> tree_backed | 2.4840 us/op | 2.4930 us/op | 1.00 |
| aggregationBits struct -> tree_backed | 2.9160 us/op | 2.8900 us/op | 1.01 |
| aggregationBits tree_backed -> struct | 1.2420 us/op | 1.2690 us/op | 0.98 |
| aggregationBits struct -> binary | 813.00 ns/op | 785.00 ns/op | 1.04 |
| aggregationBits tree_backed -> binary | 1.0990 us/op | 1.0780 us/op | 1.02 |
| List(uint8) 100000 binary -> struct | 1.5108 ms/op | 1.3611 ms/op | 1.11 |
| List(uint8) 100000 binary -> tree_backed | 93.314 us/op | 91.721 us/op | 1.02 |
| List(uint8) 100000 struct -> tree_backed | 1.1414 ms/op | 1.1277 ms/op | 1.01 |
| List(uint8) 100000 tree_backed -> struct | 1.0896 ms/op | 1.0331 ms/op | 1.05 |
| List(uint8) 100000 struct -> binary | 980.80 us/op | 1.0071 ms/op | 0.97 |
| List(uint8) 100000 tree_backed -> binary | 92.957 us/op | 91.519 us/op | 1.02 |
| List(uint64Number) 100000 binary -> struct | 1.1630 ms/op | 1.1941 ms/op | 0.97 |
| List(uint64Number) 100000 binary -> tree_backed | 3.7069 ms/op | 3.2774 ms/op | 1.13 |
| List(uint64Number) 100000 struct -> tree_backed | 5.4334 ms/op | 4.8642 ms/op | 1.12 |
| List(uint64Number) 100000 tree_backed -> struct | 2.3291 ms/op | 2.1910 ms/op | 1.06 |
| List(uint64Number) 100000 struct -> binary | 1.4126 ms/op | 1.3603 ms/op | 1.04 |
| List(uint64Number) 100000 tree_backed -> binary | 880.05 us/op | 905.49 us/op | 0.97 |
| List(Uint64Bigint) 100000 binary -> struct | 3.6164 ms/op | 3.7756 ms/op | 0.96 |
| List(Uint64Bigint) 100000 binary -> tree_backed | 3.0403 ms/op | 3.6574 ms/op | 0.83 |
| List(Uint64Bigint) 100000 struct -> tree_backed | 5.5139 ms/op | 5.6519 ms/op | 0.98 |
| List(Uint64Bigint) 100000 tree_backed -> struct | 4.5104 ms/op | 4.6726 ms/op | 0.97 |
| List(Uint64Bigint) 100000 struct -> binary | 2.0430 ms/op | 2.0692 ms/op | 0.99 |
| List(Uint64Bigint) 100000 tree_backed -> binary | 932.86 us/op | 861.91 us/op | 1.08 |
| Vector(Root) 100000 binary -> struct | 31.913 ms/op | 30.952 ms/op | 1.03 |
| Vector(Root) 100000 binary -> tree_backed | 29.793 ms/op | 34.539 ms/op | 0.86 |
| Vector(Root) 100000 struct -> tree_backed | 39.009 ms/op | 39.299 ms/op | 0.99 |
| Vector(Root) 100000 tree_backed -> struct | 44.624 ms/op | 45.190 ms/op | 0.99 |
| Vector(Root) 100000 struct -> binary | 2.6021 ms/op | 2.6132 ms/op | 1.00 |
| Vector(Root) 100000 tree_backed -> binary | 8.5318 ms/op | 9.2572 ms/op | 0.92 |
| List(Validator) 100000 binary -> struct | 100.98 ms/op | 108.52 ms/op | 0.93 |
| List(Validator) 100000 binary -> tree_backed | 265.76 ms/op | 296.50 ms/op | 0.90 |
| List(Validator) 100000 struct -> tree_backed | 302.69 ms/op | 301.50 ms/op | 1.00 |
| List(Validator) 100000 tree_backed -> struct | 195.51 ms/op | 205.86 ms/op | 0.95 |
| List(Validator) 100000 struct -> binary | 27.193 ms/op | 27.630 ms/op | 0.98 |
| List(Validator) 100000 tree_backed -> binary | 113.41 ms/op | 115.33 ms/op | 0.98 |
| List(Validator-NS) 100000 binary -> struct | 101.00 ms/op | 111.86 ms/op | 0.90 |
| List(Validator-NS) 100000 binary -> tree_backed | 137.72 ms/op | 152.60 ms/op | 0.90 |
| List(Validator-NS) 100000 struct -> tree_backed | 201.15 ms/op | 190.75 ms/op | 1.05 |
| List(Validator-NS) 100000 tree_backed -> struct | 166.49 ms/op | 167.24 ms/op | 1.00 |
| List(Validator-NS) 100000 struct -> binary | 26.816 ms/op | 26.850 ms/op | 1.00 |
| List(Validator-NS) 100000 tree_backed -> binary | 31.949 ms/op | 32.632 ms/op | 0.98 |
| get epochStatuses - MutableVector | 109.22 us/op | 122.77 us/op | 0.89 |
| get epochStatuses - ViewDU | 204.56 us/op | 201.22 us/op | 1.02 |
| set epochStatuses - ListTreeView | 2.4986 ms/op | 1.6703 ms/op | 1.50 |
| set epochStatuses - ListTreeView - set() | 443.46 us/op | 468.48 us/op | 0.95 |
| set epochStatuses - ListTreeView - commit() | 528.75 us/op | 573.78 us/op | 0.92 |
| bitstring | 649.40 ns/op | 643.23 ns/op | 1.01 |
| bit mask | 13.571 ns/op | 14.083 ns/op | 0.96 |
| struct - increase slot to 1000000 | 940.89 us/op | 927.89 us/op | 1.01 |
| UintNumberType - increase slot to 1000000 | 21.370 ms/op | 22.282 ms/op | 0.96 |
| UintBigintType - increase slot to 1000000 | 163.32 ms/op | 166.33 ms/op | 0.98 |
| UintBigint8 x 100000 tree_deserialize | 4.7695 ms/op | 4.9297 ms/op | 0.97 |
| UintBigint8 x 100000 tree_serialize | 1.0990 ms/op | 1.0926 ms/op | 1.01 |
| UintBigint16 x 100000 tree_deserialize | 4.4081 ms/op | 4.9484 ms/op | 0.89 |
| UintBigint16 x 100000 tree_serialize | 1.2411 ms/op | 1.2837 ms/op | 0.97 |
| UintBigint32 x 100000 tree_deserialize | 5.2003 ms/op | 5.2379 ms/op | 0.99 |
| UintBigint32 x 100000 tree_serialize | 1.2333 ms/op | 1.2957 ms/op | 0.95 |
| UintBigint64 x 100000 tree_deserialize | 5.6042 ms/op | 5.5047 ms/op | 1.02 |
| UintBigint64 x 100000 tree_serialize | 1.6067 ms/op | 1.6591 ms/op | 0.97 |
| UintBigint8 x 100000 value_deserialize | 433.79 us/op | 433.58 us/op | 1.00 |
| UintBigint8 x 100000 value_serialize | 666.03 us/op | 721.92 us/op | 0.92 |
| UintBigint16 x 100000 value_deserialize | 464.11 us/op | 463.87 us/op | 1.00 |
| UintBigint16 x 100000 value_serialize | 730.73 us/op | 779.96 us/op | 0.94 |
| UintBigint32 x 100000 value_deserialize | 436.05 us/op | 433.05 us/op | 1.01 |
| UintBigint32 x 100000 value_serialize | 712.92 us/op | 764.62 us/op | 0.93 |
| UintBigint64 x 100000 value_deserialize | 498.64 us/op | 496.00 us/op | 1.01 |
| UintBigint64 x 100000 value_serialize | 893.69 us/op | 935.17 us/op | 0.96 |
| UintBigint8 x 100000 deserialize | 3.4792 ms/op | 3.3991 ms/op | 1.02 |
| UintBigint8 x 100000 serialize | 1.6493 ms/op | 1.5510 ms/op | 1.06 |
| UintBigint16 x 100000 deserialize | 3.3701 ms/op | 3.3767 ms/op | 1.00 |
| UintBigint16 x 100000 serialize | 1.6628 ms/op | 1.6018 ms/op | 1.04 |
| UintBigint32 x 100000 deserialize | 3.8339 ms/op | 3.5770 ms/op | 1.07 |
| UintBigint32 x 100000 serialize | 3.0730 ms/op | 2.9731 ms/op | 1.03 |
| UintBigint64 x 100000 deserialize | 4.3856 ms/op | 4.2846 ms/op | 1.02 |
| UintBigint64 x 100000 serialize | 1.5563 ms/op | 1.5770 ms/op | 0.99 |
| UintBigint128 x 100000 deserialize | 5.5363 ms/op | 6.0226 ms/op | 0.92 |
| UintBigint128 x 100000 serialize | 15.208 ms/op | 14.634 ms/op | 1.04 |
| UintBigint256 x 100000 deserialize | 9.0692 ms/op | 7.9220 ms/op | 1.14 |
| UintBigint256 x 100000 serialize | 44.628 ms/op | 42.564 ms/op | 1.05 |
| Slice from Uint8Array x25000 | 1.3526 ms/op | 1.2222 ms/op | 1.11 |
| Slice from ArrayBuffer x25000 | 17.451 ms/op | 15.521 ms/op | 1.12 |
| Slice from ArrayBuffer x25000 + new Uint8Array | 18.821 ms/op | 15.437 ms/op | 1.22 |
| Copy Uint8Array 100000 iterate | 1.6790 ms/op | 1.6754 ms/op | 1.00 |
| Copy Uint8Array 100000 slice | 113.83 us/op | 115.84 us/op | 0.98 |
| Copy Uint8Array 100000 Uint8Array.prototype.slice.call | 112.68 us/op | 112.79 us/op | 1.00 |
| Copy Buffer 100000 Uint8Array.prototype.slice.call | 116.07 us/op | 113.59 us/op | 1.02 |
| Copy Uint8Array 100000 slice + set | 193.76 us/op | 169.80 us/op | 1.14 |
| Copy Uint8Array 100000 subarray + set | 115.69 us/op | 112.90 us/op | 1.02 |
| Copy Uint8Array 100000 slice arrayBuffer | 117.00 us/op | 114.07 us/op | 1.03 |
| Uint64 deserialize 100000 - iterate Uint8Array | 1.9288 ms/op | 1.7962 ms/op | 1.07 |
| Uint64 deserialize 100000 - by Uint32A | 1.9591 ms/op | 1.8299 ms/op | 1.07 |
| Uint64 deserialize 100000 - by DataView.getUint32 x2 | 1.9538 ms/op | 1.8006 ms/op | 1.09 |
| Uint64 deserialize 100000 - by DataView.getBigUint64 | 5.0710 ms/op | 4.9245 ms/op | 1.03 |
| Uint64 deserialize 100000 - by byte | 40.132 ms/op | 40.026 ms/op | 1.00 |
by benchmarkbot/action
this was tested in lodestar, see https://github.com/ChainSafe/lodestar/pull/7171#issuecomment-2425472397
prefer to get this PR #409 to be reviewed first