Skip to content

Conversation

@twoeths
Copy link
Contributor

@twoeths twoeths commented Aug 27, 2025

Motivation

  • improve the time to deserialize hex, especially for getBlobsV2() where each blob is 131kb
  • if the benchmark is correct, we can expect the time to deserialize blob hex from 332.6842 ms/op to more or less 2ms
  • will apply it for getBlobsV2() in the next PR by preallocate some memory and reuse it for all slots

Description

  • implement fromHexInto() using String.charCodeAt() for browser and use that for NodeJs as well
  • the Buffer/NodeJS implementation is too bad that I only maintain it in the benchmark

Test result on a regular lodestar node

  • browser fromHexInto(blob) is 1000x faster than browser fromHex(blob) and >100x faster than nodejs fromHexInto(blob)
packages/utils/test/perf/bytes.test.ts
  bytes utils
    ✔ nodejs block root to RootHex using toHex                             2817687 ops/s    354.9010 ns/op        -       1324 runs  0.897 s
    ✔ nodejs block root to RootHex using toRootHex                         4369044 ops/s    228.8830 ns/op        -       1793 runs  0.902 s
    ✔ nodejs fromhex(blob)                                                3.005854 ops/s    332.6842 ms/op        -         10 runs   4.18 s
    ✔ nodejs fromHexInto(blob)                                            3.617654 ops/s    276.4222 ms/op        -         10 runs   3.36 s
    ✔ browser block root to RootHex using the deprecated toHexString       1656696 ops/s    603.6110 ns/op        -        963 runs   1.34 s
    ✔ browser block root to RootHex using toHex                            2060611 ops/s    485.2930 ns/op        -        424 runs  0.812 s
    ✔ browser block root to RootHex using toRootHex                        2320476 ops/s    430.9460 ns/op        -        889 runs  0.841 s
    ✔ browser fromHexInto(blob)                                           503.7166 ops/s    1.985243 ms/op        -         10 runs   21.9 s
    ✔ browser fromHex(blob)                                              0.5095370 ops/s    1.962566  s/op        -         10 runs   21.7 s

@codecov
Copy link

codecov bot commented Aug 27, 2025

Codecov Report

❌ Patch coverage is 68.96552% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.23%. Comparing base (923176c) to head (28f76ee).
⚠️ Report is 4 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #8275      +/-   ##
============================================
- Coverage     54.25%   54.23%   -0.02%     
============================================
  Files           847      847              
  Lines         63852    63844       -8     
  Branches       4835     4839       +4     
============================================
- Hits          34640    34625      -15     
- Misses        29135    29142       +7     
  Partials         77       77              
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 27, 2025

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 7b3d223 Previous: 44611dc Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 939.61 us/op 1.0179 ms/op 0.92
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 35.837 us/op 38.157 us/op 0.94
BLS verify - blst 829.76 us/op 867.59 us/op 0.96
BLS verifyMultipleSignatures 3 - blst 1.1960 ms/op 1.3143 ms/op 0.91
BLS verifyMultipleSignatures 8 - blst 1.6446 ms/op 1.7838 ms/op 0.92
BLS verifyMultipleSignatures 32 - blst 4.8736 ms/op 4.8680 ms/op 1.00
BLS verifyMultipleSignatures 64 - blst 9.0043 ms/op 10.132 ms/op 0.89
BLS verifyMultipleSignatures 128 - blst 17.172 ms/op 17.191 ms/op 1.00
BLS deserializing 10000 signatures 692.93 ms/op 691.40 ms/op 1.00
BLS deserializing 100000 signatures 6.9426 s/op 7.0044 s/op 0.99
BLS verifyMultipleSignatures - same message - 3 - blst 919.80 us/op 999.93 us/op 0.92
BLS verifyMultipleSignatures - same message - 8 - blst 1.0052 ms/op 1.0696 ms/op 0.94
BLS verifyMultipleSignatures - same message - 32 - blst 1.6686 ms/op 1.8618 ms/op 0.90
BLS verifyMultipleSignatures - same message - 64 - blst 2.6161 ms/op 2.7574 ms/op 0.95
BLS verifyMultipleSignatures - same message - 128 - blst 4.4309 ms/op 4.4505 ms/op 1.00
BLS aggregatePubkeys 32 - blst 19.646 us/op 19.882 us/op 0.99
BLS aggregatePubkeys 128 - blst 71.123 us/op 71.338 us/op 1.00
notSeenSlots=1 numMissedVotes=1 numBadVotes=10 48.381 ms/op 54.595 ms/op 0.89
notSeenSlots=1 numMissedVotes=0 numBadVotes=4 47.560 ms/op 50.892 ms/op 0.93
notSeenSlots=2 numMissedVotes=1 numBadVotes=10 37.137 ms/op 36.653 ms/op 1.01
getSlashingsAndExits - default max 74.924 us/op 72.625 us/op 1.03
getSlashingsAndExits - 2k 331.01 us/op 297.72 us/op 1.11
proposeBlockBody type=full, size=empty 6.8109 ms/op 5.5928 ms/op 1.22
isKnown best case - 1 super set check 220.00 ns/op 211.00 ns/op 1.04
isKnown normal case - 2 super set checks 216.00 ns/op 206.00 ns/op 1.05
isKnown worse case - 16 super set checks 213.00 ns/op 207.00 ns/op 1.03
InMemoryCheckpointStateCache - add get delete 2.4440 us/op 2.3710 us/op 1.03
validate api signedAggregateAndProof - struct 1.3831 ms/op 1.3691 ms/op 1.01
validate gossip signedAggregateAndProof - struct 1.3772 ms/op 1.4224 ms/op 0.97
batch validate gossip attestation - vc 640000 - chunk 32 117.86 us/op 114.83 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 64 103.44 us/op 101.49 us/op 1.02
batch validate gossip attestation - vc 640000 - chunk 128 95.878 us/op 94.984 us/op 1.01
batch validate gossip attestation - vc 640000 - chunk 256 99.024 us/op 96.662 us/op 1.02
pickEth1Vote - no votes 962.46 us/op 956.03 us/op 1.01
pickEth1Vote - max votes 6.8521 ms/op 5.5688 ms/op 1.23
pickEth1Vote - Eth1Data hashTreeRoot value x2048 11.972 ms/op 11.576 ms/op 1.03
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 18.682 ms/op 14.374 ms/op 1.30
pickEth1Vote - Eth1Data fastSerialize value x2048 455.74 us/op 412.50 us/op 1.10
pickEth1Vote - Eth1Data fastSerialize tree x2048 2.1374 ms/op 2.8170 ms/op 0.76
bytes32 toHexString 364.00 ns/op 358.00 ns/op 1.02
bytes32 Buffer.toString(hex) 245.00 ns/op 253.00 ns/op 0.97
bytes32 Buffer.toString(hex) from Uint8Array 335.00 ns/op 340.00 ns/op 0.99
bytes32 Buffer.toString(hex) + 0x 244.00 ns/op 250.00 ns/op 0.98
Object access 1 prop 0.12600 ns/op 0.11700 ns/op 1.08
Map access 1 prop 0.13200 ns/op 0.12400 ns/op 1.06
Object get x1000 5.7530 ns/op 5.7560 ns/op 1.00
Map get x1000 6.1870 ns/op 6.1170 ns/op 1.01
Object set x1000 31.748 ns/op 27.891 ns/op 1.14
Map set x1000 20.550 ns/op 18.975 ns/op 1.08
Return object 10000 times 0.29110 ns/op 0.28250 ns/op 1.03
Throw Error 10000 times 4.4554 us/op 4.2186 us/op 1.06
toHex 133.21 ns/op 140.17 ns/op 0.95
Buffer.from 122.10 ns/op 119.22 ns/op 1.02
shared Buffer 85.650 ns/op 84.790 ns/op 1.01
fastMsgIdFn sha256 / 200 bytes 2.1890 us/op 2.1250 us/op 1.03
fastMsgIdFn h32 xxhash / 200 bytes 212.00 ns/op 204.00 ns/op 1.04
fastMsgIdFn h64 xxhash / 200 bytes 266.00 ns/op 256.00 ns/op 1.04
fastMsgIdFn sha256 / 1000 bytes 7.4540 us/op 7.0170 us/op 1.06
fastMsgIdFn h32 xxhash / 1000 bytes 342.00 ns/op 336.00 ns/op 1.02
fastMsgIdFn h64 xxhash / 1000 bytes 338.00 ns/op 328.00 ns/op 1.03
fastMsgIdFn sha256 / 10000 bytes 65.617 us/op 64.332 us/op 1.02
fastMsgIdFn h32 xxhash / 10000 bytes 1.8740 us/op 1.7920 us/op 1.05
fastMsgIdFn h64 xxhash / 10000 bytes 1.2370 us/op 1.1780 us/op 1.05
send data - 1000 256B messages 17.914 ms/op 16.391 ms/op 1.09
send data - 1000 512B messages 22.441 ms/op 19.793 ms/op 1.13
send data - 1000 1024B messages 28.810 ms/op 27.019 ms/op 1.07
send data - 1000 1200B messages 25.842 ms/op 23.822 ms/op 1.08
send data - 1000 2048B messages 27.294 ms/op 28.094 ms/op 0.97
send data - 1000 4096B messages 30.760 ms/op 32.277 ms/op 0.95
send data - 1000 16384B messages 46.113 ms/op 47.918 ms/op 0.96
send data - 1000 65536B messages 129.41 ms/op 117.04 ms/op 1.11
enrSubnets - fastDeserialize 64 bits 920.00 ns/op 888.00 ns/op 1.04
enrSubnets - ssz BitVector 64 bits 343.00 ns/op 313.00 ns/op 1.10
enrSubnets - fastDeserialize 4 bits 140.00 ns/op 127.00 ns/op 1.10
enrSubnets - ssz BitVector 4 bits 345.00 ns/op 317.00 ns/op 1.09
prioritizePeers score -10:0 att 32-0.1 sync 2-0 241.20 us/op 234.98 us/op 1.03
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 269.64 us/op 261.82 us/op 1.03
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 397.52 us/op 374.85 us/op 1.06
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 740.35 us/op 707.61 us/op 1.05
prioritizePeers score 0:0 att 64-1 sync 4-1 914.27 us/op 849.95 us/op 1.08
array of 16000 items push then shift 1.6483 us/op 1.6038 us/op 1.03
LinkedList of 16000 items push then shift 8.8750 ns/op 6.9670 ns/op 1.27
array of 16000 items push then pop 83.455 ns/op 76.539 ns/op 1.09
LinkedList of 16000 items push then pop 7.6850 ns/op 6.8850 ns/op 1.12
array of 24000 items push then shift 2.4493 us/op 2.3894 us/op 1.03
LinkedList of 24000 items push then shift 8.0090 ns/op 6.9980 ns/op 1.14
array of 24000 items push then pop 119.39 ns/op 106.06 ns/op 1.13
LinkedList of 24000 items push then pop 8.2350 ns/op 7.4260 ns/op 1.11
intersect bitArray bitLen 8 6.4620 ns/op 6.3750 ns/op 1.01
intersect array and set length 8 39.415 ns/op 37.890 ns/op 1.04
intersect bitArray bitLen 128 29.831 ns/op 29.732 ns/op 1.00
intersect array and set length 128 641.60 ns/op 709.32 ns/op 0.90
bitArray.getTrueBitIndexes() bitLen 128 1.0330 us/op 1.0350 us/op 1.00
bitArray.getTrueBitIndexes() bitLen 248 2.1440 us/op 1.8290 us/op 1.17
bitArray.getTrueBitIndexes() bitLen 512 4.5170 us/op 3.7640 us/op 1.20
Buffer.concat 32 items 872.00 ns/op 605.00 ns/op 1.44
Uint8Array.set 32 items 1.7380 us/op 1.0320 us/op 1.68
Buffer.copy 3.2210 us/op 2.1640 us/op 1.49
Uint8Array.set - with subarray 3.1270 us/op 1.6150 us/op 1.94
Uint8Array.set - without subarray 2.1740 us/op 914.00 ns/op 2.38
getUint32 - dataview 210.00 ns/op 188.00 ns/op 1.12
getUint32 - manual 126.00 ns/op 121.00 ns/op 1.04
Set add up to 64 items then delete first 2.7299 us/op 2.2143 us/op 1.23
OrderedSet add up to 64 items then delete first 3.6100 us/op 3.3329 us/op 1.08
Set add up to 64 items then delete last 2.8575 us/op 2.5487 us/op 1.12
OrderedSet add up to 64 items then delete last 4.6194 us/op 3.7068 us/op 1.25
Set add up to 64 items then delete middle 3.1477 us/op 2.5959 us/op 1.21
OrderedSet add up to 64 items then delete middle 6.0356 us/op 5.7411 us/op 1.05
Set add up to 128 items then delete first 5.5800 us/op 5.7692 us/op 0.97
OrderedSet add up to 128 items then delete first 10.098 us/op 8.1363 us/op 1.24
Set add up to 128 items then delete last 5.3642 us/op 5.1905 us/op 1.03
OrderedSet add up to 128 items then delete last 8.8685 us/op 7.8354 us/op 1.13
Set add up to 128 items then delete middle 5.8083 us/op 5.4246 us/op 1.07
OrderedSet add up to 128 items then delete middle 16.431 us/op 16.061 us/op 1.02
Set add up to 256 items then delete first 11.227 us/op 12.216 us/op 0.92
OrderedSet add up to 256 items then delete first 20.073 us/op 17.318 us/op 1.16
Set add up to 256 items then delete last 12.547 us/op 10.580 us/op 1.19
OrderedSet add up to 256 items then delete last 18.119 us/op 14.841 us/op 1.22
Set add up to 256 items then delete middle 12.194 us/op 9.8419 us/op 1.24
OrderedSet add up to 256 items then delete middle 47.426 us/op 43.476 us/op 1.09
transfer serialized Status (84 B) 3.7630 us/op 2.2010 us/op 1.71
copy serialized Status (84 B) 1.2060 us/op 1.0840 us/op 1.11
transfer serialized SignedVoluntaryExit (112 B) 2.3600 us/op 2.1920 us/op 1.08
copy serialized SignedVoluntaryExit (112 B) 1.2040 us/op 1.0940 us/op 1.10
transfer serialized ProposerSlashing (416 B) 2.3970 us/op 2.1750 us/op 1.10
copy serialized ProposerSlashing (416 B) 1.3590 us/op 1.1490 us/op 1.18
transfer serialized Attestation (485 B) 2.6200 us/op 2.2110 us/op 1.18
copy serialized Attestation (485 B) 2.3280 us/op 1.1620 us/op 2.00
transfer serialized AttesterSlashing (33232 B) 2.7610 us/op 2.3440 us/op 1.18
copy serialized AttesterSlashing (33232 B) 4.0480 us/op 3.6800 us/op 1.10
transfer serialized Small SignedBeaconBlock (128000 B) 3.3860 us/op 3.0610 us/op 1.11
copy serialized Small SignedBeaconBlock (128000 B) 9.6930 us/op 9.7160 us/op 1.00
transfer serialized Avg SignedBeaconBlock (200000 B) 3.9230 us/op 3.5010 us/op 1.12
copy serialized Avg SignedBeaconBlock (200000 B) 17.102 us/op 14.522 us/op 1.18
transfer serialized BlobsSidecar (524380 B) 4.4200 us/op 4.2450 us/op 1.04
copy serialized BlobsSidecar (524380 B) 86.321 us/op 65.458 us/op 1.32
transfer serialized Big SignedBeaconBlock (1000000 B) 4.1440 us/op 3.9690 us/op 1.04
copy serialized Big SignedBeaconBlock (1000000 B) 162.44 us/op 112.96 us/op 1.44
pass gossip attestations to forkchoice per slot 2.8007 ms/op 2.7886 ms/op 1.00
forkChoice updateHead vc 100000 bc 64 eq 0 471.59 us/op 454.93 us/op 1.04
forkChoice updateHead vc 600000 bc 64 eq 0 2.9762 ms/op 2.8607 ms/op 1.04
forkChoice updateHead vc 1000000 bc 64 eq 0 5.0004 ms/op 4.8843 ms/op 1.02
forkChoice updateHead vc 600000 bc 320 eq 0 3.0793 ms/op 2.8763 ms/op 1.07
forkChoice updateHead vc 600000 bc 1200 eq 0 3.0183 ms/op 2.8219 ms/op 1.07
forkChoice updateHead vc 600000 bc 7200 eq 0 3.5466 ms/op 3.1362 ms/op 1.13
forkChoice updateHead vc 600000 bc 64 eq 1000 11.436 ms/op 10.457 ms/op 1.09
forkChoice updateHead vc 600000 bc 64 eq 10000 11.280 ms/op 10.490 ms/op 1.08
forkChoice updateHead vc 600000 bc 64 eq 300000 17.842 ms/op 15.083 ms/op 1.18
computeDeltas 500000 validators 300 proto nodes 4.2316 ms/op 3.9691 ms/op 1.07
computeDeltas 500000 validators 1200 proto nodes 4.3269 ms/op 4.0487 ms/op 1.07
computeDeltas 500000 validators 7200 proto nodes 4.3699 ms/op 3.9909 ms/op 1.09
computeDeltas 750000 validators 300 proto nodes 6.7785 ms/op 5.7875 ms/op 1.17
computeDeltas 750000 validators 1200 proto nodes 6.8109 ms/op 5.6725 ms/op 1.20
computeDeltas 750000 validators 7200 proto nodes 6.6524 ms/op 5.6490 ms/op 1.18
computeDeltas 1400000 validators 300 proto nodes 12.429 ms/op 10.544 ms/op 1.18
computeDeltas 1400000 validators 1200 proto nodes 12.403 ms/op 10.431 ms/op 1.19
computeDeltas 1400000 validators 7200 proto nodes 12.926 ms/op 10.452 ms/op 1.24
computeDeltas 2100000 validators 300 proto nodes 19.407 ms/op 15.722 ms/op 1.23
computeDeltas 2100000 validators 1200 proto nodes 17.247 ms/op 15.906 ms/op 1.08
computeDeltas 2100000 validators 7200 proto nodes 17.329 ms/op 16.030 ms/op 1.08
altair processAttestation - 250000 vs - 7PWei normalcase 3.1867 ms/op 2.2330 ms/op 1.43
altair processAttestation - 250000 vs - 7PWei worstcase 3.2667 ms/op 3.1366 ms/op 1.04
altair processAttestation - setStatus - 1/6 committees join 133.31 us/op 139.66 us/op 0.95
altair processAttestation - setStatus - 1/3 committees join 250.81 us/op 251.57 us/op 1.00
altair processAttestation - setStatus - 1/2 committees join 349.45 us/op 342.31 us/op 1.02
altair processAttestation - setStatus - 2/3 committees join 450.38 us/op 438.22 us/op 1.03
altair processAttestation - setStatus - 4/5 committees join 617.45 us/op 603.34 us/op 1.02
altair processAttestation - setStatus - 100% committees join 729.95 us/op 713.72 us/op 1.02
altair processBlock - 250000 vs - 7PWei normalcase 4.3580 ms/op 4.1773 ms/op 1.04
altair processBlock - 250000 vs - 7PWei normalcase hashState 28.965 ms/op 31.832 ms/op 0.91
altair processBlock - 250000 vs - 7PWei worstcase 37.332 ms/op 36.139 ms/op 1.03
altair processBlock - 250000 vs - 7PWei worstcase hashState 78.663 ms/op 70.407 ms/op 1.12
phase0 processBlock - 250000 vs - 7PWei normalcase 1.6349 ms/op 1.5358 ms/op 1.06
phase0 processBlock - 250000 vs - 7PWei worstcase 22.988 ms/op 22.414 ms/op 1.03
altair processEth1Data - 250000 vs - 7PWei normalcase 340.10 us/op 338.44 us/op 1.00
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 6.2790 us/op 6.5190 us/op 0.96
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 51.361 us/op 46.250 us/op 1.11
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 13.089 us/op 12.003 us/op 1.09
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 6.8600 us/op 7.1700 us/op 0.96
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 190.85 us/op 161.72 us/op 1.18
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 1.9138 ms/op 1.7652 ms/op 1.08
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.8402 ms/op 2.3589 ms/op 1.20
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.4036 ms/op 2.3113 ms/op 1.04
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 4.8468 ms/op 4.6710 ms/op 1.04
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.4540 ms/op 2.4075 ms/op 1.02
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.9885 ms/op 4.7594 ms/op 1.05
Tree 40 250000 create 494.83 ms/op 417.95 ms/op 1.18
Tree 40 250000 get(125000) 144.78 ns/op 150.39 ns/op 0.96
Tree 40 250000 set(125000) 1.4905 us/op 1.5145 us/op 0.98
Tree 40 250000 toArray() 17.297 ms/op 16.980 ms/op 1.02
Tree 40 250000 iterate all - toArray() + loop 17.122 ms/op 17.775 ms/op 0.96
Tree 40 250000 iterate all - get(i) 55.571 ms/op 51.597 ms/op 1.08
Array 250000 create 2.5273 ms/op 2.4156 ms/op 1.05
Array 250000 clone - spread 821.77 us/op 809.69 us/op 1.01
Array 250000 get(125000) 0.41400 ns/op 0.41300 ns/op 1.00
Array 250000 set(125000) 0.43700 ns/op 0.42700 ns/op 1.02
Array 250000 iterate all - loop 100.68 us/op 107.18 us/op 0.94
phase0 afterProcessEpoch - 250000 vs - 7PWei 42.399 ms/op 41.226 ms/op 1.03
Array.fill - length 1000000 3.7239 ms/op 3.5377 ms/op 1.05
Array push - length 1000000 13.739 ms/op 13.136 ms/op 1.05
Array.get 0.29181 ns/op 0.27445 ns/op 1.06
Uint8Array.get 0.44939 ns/op 0.43372 ns/op 1.04
phase0 beforeProcessEpoch - 250000 vs - 7PWei 18.730 ms/op 15.407 ms/op 1.22
altair processEpoch - mainnet_e81889 245.82 ms/op 277.47 ms/op 0.89
mainnet_e81889 - altair beforeProcessEpoch 20.544 ms/op 18.432 ms/op 1.11
mainnet_e81889 - altair processJustificationAndFinalization 5.4130 us/op 5.4930 us/op 0.99
mainnet_e81889 - altair processInactivityUpdates 4.1340 ms/op 4.1199 ms/op 1.00
mainnet_e81889 - altair processRewardsAndPenalties 40.738 ms/op 37.040 ms/op 1.10
mainnet_e81889 - altair processRegistryUpdates 718.00 ns/op 700.00 ns/op 1.03
mainnet_e81889 - altair processSlashings 194.00 ns/op 180.00 ns/op 1.08
mainnet_e81889 - altair processEth1DataReset 188.00 ns/op 175.00 ns/op 1.07
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.2124 ms/op 1.1776 ms/op 1.03
mainnet_e81889 - altair processSlashingsReset 899.00 ns/op 841.00 ns/op 1.07
mainnet_e81889 - altair processRandaoMixesReset 1.1890 us/op 1.2330 us/op 0.96
mainnet_e81889 - altair processHistoricalRootsUpdate 189.00 ns/op 176.00 ns/op 1.07
mainnet_e81889 - altair processParticipationFlagUpdates 557.00 ns/op 508.00 ns/op 1.10
mainnet_e81889 - altair processSyncCommitteeUpdates 151.00 ns/op 137.00 ns/op 1.10
mainnet_e81889 - altair afterProcessEpoch 45.788 ms/op 43.381 ms/op 1.06
capella processEpoch - mainnet_e217614 964.18 ms/op 907.68 ms/op 1.06
mainnet_e217614 - capella beforeProcessEpoch 66.369 ms/op 63.228 ms/op 1.05
mainnet_e217614 - capella processJustificationAndFinalization 5.4430 us/op 5.1570 us/op 1.06
mainnet_e217614 - capella processInactivityUpdates 16.433 ms/op 14.251 ms/op 1.15
mainnet_e217614 - capella processRewardsAndPenalties 176.26 ms/op 176.88 ms/op 1.00
mainnet_e217614 - capella processRegistryUpdates 6.6810 us/op 6.3680 us/op 1.05
mainnet_e217614 - capella processSlashings 213.00 ns/op 170.00 ns/op 1.25
mainnet_e217614 - capella processEth1DataReset 191.00 ns/op 168.00 ns/op 1.14
mainnet_e217614 - capella processEffectiveBalanceUpdates 4.4229 ms/op 4.1212 ms/op 1.07
mainnet_e217614 - capella processSlashingsReset 911.00 ns/op 856.00 ns/op 1.06
mainnet_e217614 - capella processRandaoMixesReset 1.2330 us/op 1.1940 us/op 1.03
mainnet_e217614 - capella processHistoricalRootsUpdate 190.00 ns/op 172.00 ns/op 1.10
mainnet_e217614 - capella processParticipationFlagUpdates 573.00 ns/op 506.00 ns/op 1.13
mainnet_e217614 - capella afterProcessEpoch 119.40 ms/op 129.97 ms/op 0.92
phase0 processEpoch - mainnet_e58758 305.00 ms/op 263.95 ms/op 1.16
mainnet_e58758 - phase0 beforeProcessEpoch 77.246 ms/op 72.235 ms/op 1.07
mainnet_e58758 - phase0 processJustificationAndFinalization 5.7740 us/op 7.0570 us/op 0.82
mainnet_e58758 - phase0 processRewardsAndPenalties 35.885 ms/op 38.902 ms/op 0.92
mainnet_e58758 - phase0 processRegistryUpdates 3.3020 us/op 3.2360 us/op 1.02
mainnet_e58758 - phase0 processSlashings 189.00 ns/op 174.00 ns/op 1.09
mainnet_e58758 - phase0 processEth1DataReset 189.00 ns/op 169.00 ns/op 1.12
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.1884 ms/op 1.1599 ms/op 1.02
mainnet_e58758 - phase0 processSlashingsReset 952.00 ns/op 914.00 ns/op 1.04
mainnet_e58758 - phase0 processRandaoMixesReset 1.1760 us/op 1.1650 us/op 1.01
mainnet_e58758 - phase0 processHistoricalRootsUpdate 189.00 ns/op 170.00 ns/op 1.11
mainnet_e58758 - phase0 processParticipationRecordUpdates 910.00 ns/op 900.00 ns/op 1.01
mainnet_e58758 - phase0 afterProcessEpoch 36.351 ms/op 35.279 ms/op 1.03
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.4247 ms/op 1.3482 ms/op 1.06
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.1920 ms/op 2.7954 ms/op 0.78
altair processInactivityUpdates - 250000 normalcase 16.859 ms/op 20.193 ms/op 0.83
altair processInactivityUpdates - 250000 worstcase 19.144 ms/op 18.959 ms/op 1.01
phase0 processRegistryUpdates - 250000 normalcase 8.1980 us/op 7.7310 us/op 1.06
phase0 processRegistryUpdates - 250000 badcase_full_deposits 281.76 us/op 264.99 us/op 1.06
phase0 processRegistryUpdates - 250000 worstcase 0.5 102.29 ms/op 103.71 ms/op 0.99
altair processRewardsAndPenalties - 250000 normalcase 27.872 ms/op 27.895 ms/op 1.00
altair processRewardsAndPenalties - 250000 worstcase 25.317 ms/op 27.062 ms/op 0.94
phase0 getAttestationDeltas - 250000 normalcase 8.0503 ms/op 7.6911 ms/op 1.05
phase0 getAttestationDeltas - 250000 worstcase 6.3055 ms/op 6.5618 ms/op 0.96
phase0 processSlashings - 250000 worstcase 117.97 us/op 90.234 us/op 1.31
altair processSyncCommitteeUpdates - 250000 11.201 ms/op 10.962 ms/op 1.02
BeaconState.hashTreeRoot - No change 234.00 ns/op 207.00 ns/op 1.13
BeaconState.hashTreeRoot - 1 full validator 79.617 us/op 82.682 us/op 0.96
BeaconState.hashTreeRoot - 32 full validator 884.75 us/op 760.11 us/op 1.16
BeaconState.hashTreeRoot - 512 full validator 11.438 ms/op 8.8665 ms/op 1.29
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 94.099 us/op 88.252 us/op 1.07
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.3342 ms/op 1.2434 ms/op 1.07
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 22.926 ms/op 18.516 ms/op 1.24
BeaconState.hashTreeRoot - 1 balances 73.615 us/op 70.484 us/op 1.04
BeaconState.hashTreeRoot - 32 balances 697.65 us/op 668.77 us/op 1.04
BeaconState.hashTreeRoot - 512 balances 7.5456 ms/op 6.9870 ms/op 1.08
BeaconState.hashTreeRoot - 250000 balances 158.34 ms/op 168.04 ms/op 0.94
aggregationBits - 2048 els - zipIndexesInBitList 23.840 us/op 21.320 us/op 1.12
byteArrayEquals 32 55.249 ns/op 52.945 ns/op 1.04
Buffer.compare 32 17.615 ns/op 17.060 ns/op 1.03
byteArrayEquals 1024 1.6393 us/op 1.5658 us/op 1.05
Buffer.compare 1024 25.395 ns/op 24.664 ns/op 1.03
byteArrayEquals 16384 25.968 us/op 25.008 us/op 1.04
Buffer.compare 16384 185.66 ns/op 201.36 ns/op 0.92
byteArrayEquals 123687377 196.14 ms/op 190.07 ms/op 1.03
Buffer.compare 123687377 7.3733 ms/op 7.7487 ms/op 0.95
byteArrayEquals 32 - diff last byte 53.409 ns/op 52.445 ns/op 1.02
Buffer.compare 32 - diff last byte 17.447 ns/op 21.097 ns/op 0.83
byteArrayEquals 1024 - diff last byte 1.6103 us/op 1.5717 us/op 1.02
Buffer.compare 1024 - diff last byte 26.467 ns/op 25.734 ns/op 1.03
byteArrayEquals 16384 - diff last byte 25.740 us/op 25.070 us/op 1.03
Buffer.compare 16384 - diff last byte 207.35 ns/op 188.83 ns/op 1.10
byteArrayEquals 123687377 - diff last byte 198.30 ms/op 185.39 ms/op 1.07
Buffer.compare 123687377 - diff last byte 10.257 ms/op 6.1275 ms/op 1.67
byteArrayEquals 32 - random bytes 5.2660 ns/op 5.0330 ns/op 1.05
Buffer.compare 32 - random bytes 17.712 ns/op 16.440 ns/op 1.08
byteArrayEquals 1024 - random bytes 5.2570 ns/op 5.0300 ns/op 1.05
Buffer.compare 1024 - random bytes 17.742 ns/op 16.493 ns/op 1.08
byteArrayEquals 16384 - random bytes 5.2290 ns/op 5.0170 ns/op 1.04
Buffer.compare 16384 - random bytes 17.944 ns/op 16.488 ns/op 1.09
byteArrayEquals 123687377 - random bytes 6.5400 ns/op 6.3000 ns/op 1.04
Buffer.compare 123687377 - random bytes 18.760 ns/op 17.940 ns/op 1.05
regular array get 100000 times 34.025 us/op 32.027 us/op 1.06
wrappedArray get 100000 times 34.353 us/op 32.182 us/op 1.07
arrayWithProxy get 100000 times 12.360 ms/op 11.759 ms/op 1.05
ssz.Root.equals 47.597 ns/op 44.969 ns/op 1.06
byteArrayEquals 46.721 ns/op 44.047 ns/op 1.06
Buffer.compare 10.668 ns/op 10.071 ns/op 1.06
processSlot - 1 slots 10.679 us/op 9.9270 us/op 1.08
processSlot - 32 slots 2.2297 ms/op 2.4619 ms/op 0.91
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 3.6567 ms/op 2.7982 ms/op 1.31
getCommitteeAssignments - req 1 vs - 250000 vc 2.1821 ms/op 2.0296 ms/op 1.08
getCommitteeAssignments - req 100 vs - 250000 vc 4.2381 ms/op 3.9432 ms/op 1.07
getCommitteeAssignments - req 1000 vs - 250000 vc 4.5270 ms/op 4.2434 ms/op 1.07
findModifiedValidators - 10000 modified validators 824.92 ms/op 742.46 ms/op 1.11
findModifiedValidators - 1000 modified validators 810.62 ms/op 700.84 ms/op 1.16
findModifiedValidators - 100 modified validators 414.61 ms/op 251.27 ms/op 1.65
findModifiedValidators - 10 modified validators 379.31 ms/op 167.90 ms/op 2.26
findModifiedValidators - 1 modified validators 250.43 ms/op 166.41 ms/op 1.50
findModifiedValidators - no difference 258.51 ms/op 151.85 ms/op 1.70
compare ViewDUs 7.0956 s/op 6.5546 s/op 1.08
compare each validator Uint8Array 1.3935 s/op 1.5602 s/op 0.89
compare ViewDU to Uint8Array 1.3777 s/op 986.24 ms/op 1.40
migrate state 1000000 validators, 24 modified, 0 new 926.00 ms/op 845.77 ms/op 1.09
migrate state 1000000 validators, 1700 modified, 1000 new 1.2686 s/op 1.1381 s/op 1.11
migrate state 1000000 validators, 3400 modified, 2000 new 1.3290 s/op 1.3057 s/op 1.02
migrate state 1500000 validators, 24 modified, 0 new 926.25 ms/op 775.71 ms/op 1.19
migrate state 1500000 validators, 1700 modified, 1000 new 1.1294 s/op 988.92 ms/op 1.14
migrate state 1500000 validators, 3400 modified, 2000 new 1.4070 s/op 1.2826 s/op 1.10
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.4800 ns/op 4.1300 ns/op 1.08
state getBlockRootAtSlot - 250000 vs - 7PWei 472.14 ns/op 546.37 ns/op 0.86
naive computeProposerIndex 100000 validators 54.801 ms/op 46.480 ms/op 1.18
computeProposerIndex 100000 validators 1.5221 ms/op 1.4761 ms/op 1.03
naiveGetNextSyncCommitteeIndices 1000 validators 8.5385 s/op 7.0947 s/op 1.20
getNextSyncCommitteeIndices 1000 validators 119.35 ms/op 108.69 ms/op 1.10
naiveGetNextSyncCommitteeIndices 10000 validators 8.0682 s/op 7.5474 s/op 1.07
getNextSyncCommitteeIndices 10000 validators 117.25 ms/op 108.19 ms/op 1.08
naiveGetNextSyncCommitteeIndices 100000 validators 8.8532 s/op 7.1651 s/op 1.24
getNextSyncCommitteeIndices 100000 validators 128.84 ms/op 107.65 ms/op 1.20
naive computeShuffledIndex 100000 validators 29.140 s/op 22.858 s/op 1.27
cached computeShuffledIndex 100000 validators 657.77 ms/op 537.81 ms/op 1.22
naive computeShuffledIndex 2000000 validators 585.06 s/op 467.26 s/op 1.25
cached computeShuffledIndex 2000000 validators 51.824 s/op 27.776 s/op 1.87
computeProposers - vc 250000 652.50 us/op 593.52 us/op 1.10
computeEpochShuffling - vc 250000 45.421 ms/op 39.918 ms/op 1.14
getNextSyncCommittee - vc 250000 11.150 ms/op 9.9305 ms/op 1.12
computeSigningRoot for AttestationData 23.794 us/op 21.177 us/op 1.12
hash AttestationData serialized data then Buffer.toString(base64) 1.6128 us/op 1.5418 us/op 1.05
toHexString serialized data 1.2204 us/op 1.0714 us/op 1.14
Buffer.toString(base64) 150.26 ns/op 156.63 ns/op 0.96
nodejs block root to RootHex using toHex 134.64 ns/op 138.26 ns/op 0.97
nodejs block root to RootHex using toRootHex 86.379 ns/op 94.085 ns/op 0.92
nodejs fromhex(blob) 115.16 ms/op
nodejs fromHexInto(blob) 96.064 ms/op
browser block root to RootHex using the deprecated toHexString 225.45 ns/op 207.10 ns/op 1.09
browser block root to RootHex using toHex 218.62 ns/op 174.05 ns/op 1.26
browser block root to RootHex using toRootHex 167.43 ns/op 156.64 ns/op 1.07
browser fromHexInto(blob) 848.76 us/op
browser fromHex(blob) 834.57 ms/op

by benchmarkbot/action

@twoeths twoeths marked this pull request as ready for review August 27, 2025 12:56
@twoeths twoeths requested a review from a team as a code owner August 27, 2025 12:56
@wemeetagain
Copy link
Member

Seeing the opposite using Bun. Will be interesting and important to rebench when we start using Bun.

    ✔ bun Uint8Array.fromHex                                              25639.05 ops/s    39.00300 us/op        -       8286 runs  0.404 s
    ✔ bun Buffer.from                                                     7060.751 ops/s    141.6280 us/op        -       4273 runs  0.784 s
    ✔ bun lodestar's fromHexInto                                          1652.469 ops/s    605.1550 us/op        -       1001 runs   1.11 s

@wemeetagain wemeetagain merged commit afdf325 into unstable Aug 27, 2025
21 checks passed
@wemeetagain wemeetagain deleted the te/get_blobs_v2_from_hex_into branch August 27, 2025 13:20
@philknows philknows mentioned this pull request Aug 27, 2025
12 tasks
@wemeetagain
Copy link
Member

🎉 This PR is included in v1.34.0 🎉

wemeetagain added a commit that referenced this pull request Oct 23, 2025
**Motivation**

- #7280 

**Description**

- Build upon the isomorphic bytes code in the utils package
- refactor browser/nodejs selection to use conditional imports (like how
we've been handling bun / nodejs selection
- Use Uint8Array.fromHex and toHex (mentioned in
#8275 (comment))
- Refactor the bytes perf tests to include bun
- Add lodestar-bun dependency (also add missing dependency in
beacon-node package)

Results from my machine
```
  bytes utils
    ✔ nodejs block root to RootHex using toHex                             5500338 ops/s    181.8070 ns/op        -       1048 runs  0.444 s
    ✔ nodejs block root to RootHex using toRootHex                         7466866 ops/s    133.9250 ns/op        -       2189 runs  0.477 s
    ✔ nodejs fromHex(blob)                                                7001.930 ops/s    142.8178 us/op        -         10 runs   1.94 s
    ✔ nodejs fromHexInto(blob)                                            1744.298 ops/s    573.2965 us/op        -         10 runs   6.33 s
    ✔ nodejs block root to RootHex using the deprecated toHexString        1609510 ops/s    621.3070 ns/op        -        309 runs  0.704 s
    ✔ browser block root to RootHex using toHex                            1854390 ops/s    539.2610 ns/op        -        522 runs  0.807 s
    ✔ browser block root to RootHex using toRootHex                        2060543 ops/s    485.3090 ns/op        -        597 runs  0.805 s
    ✔ browser fromHex(blob)                                               1632.601 ops/s    612.5196 us/op        -         10 runs   6.77 s
    ✔ browser fromHexInto(blob)                                           1751.718 ops/s    570.8683 us/op        -         10 runs   6.36 s
    ✔ browser block root to RootHex using the deprecated toHexString       1596024 ops/s    626.5570 ns/op        -        457 runs  0.805 s
    ✔ bun block root to RootHex using toHex                            1.249563e+7 ops/s    80.02800 ns/op        -       4506 runs  0.518 s
    ✔ bun block root to RootHex using toRootHex                        1.262626e+7 ops/s    79.20000 ns/op        -       3716 runs  0.409 s
    ✔ bun fromHex(blob)                                                   26995.09 ops/s    37.04377 us/op        -         10 runs  0.899 s
    ✔ bun fromHexInto(blob)                                               31539.09 ops/s    31.70668 us/op        -         13 runs  0.914 s
    ✔ bun block root to RootHex using the deprecated toHexString       1.252944e+7 ops/s    79.81200 ns/op        -       3616 runs  0.414 s
```
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.

4 participants