mirror of
https://github.com/ChainSafe/lodestar.git
synced 2026-01-09 15:48:08 -05:00
**Motivation** - it takes so much time to run benchmark, a lot of them does not make sense - seeing OOM with NodeJS 24, see https://github.com/ChainSafe/lodestar/pull/8645#issuecomment-3601327203 **Description** - remove benchmarks for flow that's not used in prod - remove some "minMs" option for some tests that causes a lot of time - remote test that does not reflect the bottle neck of lodestar's performance as of Dec 2025 - remote tests that's not part of lodestar code. It's only meaningful in the scope of that PR only this is based on the long running test I found in https://github.com/ChainSafe/lodestar/actions/runs/19874295397/job/56957698411 ``` packages/beacon-node/test/perf/chain/validation/attestation.test.ts validate gossip attestation ✔ batch validate gossip attestation - vc 640000 - chunk 32 8931.657 ops/s 111.9613 us/op x0.918 7814 runs 30.0 s ✔ batch validate gossip attestation - vc 640000 - chunk 64 9972.473 ops/s 100.2760 us/op x0.926 4321 runs 30.1 s ✔ batch validate gossip attestation - vc 640000 - chunk 128 10569.62 ops/s 94.61075 us/op x0.921 2268 runs 30.0 s ✔ batch validate gossip attestation - vc 640000 - chunk 256 10069.74 ops/s 99.30746 us/op x0.901 1154 runs 30.1 s packages/fork-choice/test/perf/protoArray/computeDeltas.test.ts computeDeltas ✔ computeDeltas 1400000 validators 0% inactive 73.51301 ops/s 13.60303 ms/op x0.986 539 runs 10.0 s ✔ computeDeltas 1400000 validators 10% inactive 78.91095 ops/s 12.67251 ms/op x0.989 556 runs 10.0 s ✔ computeDeltas 1400000 validators 20% inactive 86.73608 ops/s 11.52923 ms/op x1.001 598 runs 10.0 s ✔ computeDeltas 1400000 validators 50% inactive 114.8443 ops/s 8.707439 ms/op x0.990 799 runs 10.0 s ✔ computeDeltas 2100000 validators 0% inactive 48.69939 ops/s 20.53414 ms/op x0.996 371 runs 10.0 s ✔ computeDeltas 2100000 validators 10% inactive 53.13929 ops/s 18.81847 ms/op x1.000 371 runs 10.0 s ✔ computeDeltas 2100000 validators 20% inactive 60.11017 ops/s 16.63612 ms/op x0.978 418 runs 10.0 s ✔ computeDeltas 2100000 validators 50% inactive 79.46802 ops/s 12.58368 ms/op x0.967 552 runs 10.0 s packages/state-transition/test/perf/util/loadState/findModifiedValidators.test.ts find modified validators by different ways serialize validators then findModifiedValidators ✔ findModifiedValidators - 10000 modified validators 1.382729 ops/s 723.2076 ms/op x0.993 10 runs 9.21 s ✔ findModifiedValidators - 1000 modified validators 1.298120 ops/s 770.3450 ms/op x1.152 10 runs 8.68 s ✔ findModifiedValidators - 100 modified validators 3.535168 ops/s 282.8720 ms/op x1.329 10 runs 3.85 s ✔ findModifiedValidators - 10 modified validators 4.648368 ops/s 215.1293 ms/op x1.548 10 runs 3.13 s ✔ findModifiedValidators - 1 modified validators 5.296754 ops/s 188.7949 ms/op x1.187 10 runs 3.10 s ✔ findModifiedValidators - no difference 3.873496 ops/s 258.1647 ms/op x1.236 12 runs 3.88 s deserialize validators then compare validator ViewDUs ✔ compare ViewDUs 0.1524038 ops/s 6.561514 s/op x1.077 9 runs 65.7 s serialize each validator then compare Uin8Array ✔ compare each validator Uint8Array 0.8007866 ops/s 1.248772 s/op x0.830 10 runs 13.7 s compare validator ViewDU to Uint8Array ✔ compare ViewDU to Uint8Array 0.9549799 ops/s 1.047143 s/op x0.999 10 runs 11.5 s packages/state-transition/test/perf/util/loadState/loadState.test.ts loadState ✔ migrate state 1000000 validators, 24 modified, 0 new 0.9790753 ops/s 1.021372 s/op x1.147 57 runs 60.1 s ✔ migrate state 1000000 validators, 1700 modified, 1000 new 0.7290797 ops/s 1.371592 s/op x0.942 43 runs 61.1 s ✔ migrate state 1000000 validators, 3400 modified, 2000 new 0.6307866 ops/s 1.585322 s/op x0.883 37 runs 60.9 s ✔ migrate state 1500000 validators, 24 modified, 0 new 0.9393088 ops/s 1.064613 s/op x0.911 55 runs 60.5 s ✔ migrate state 1500000 validators, 1700 modified, 1000 new 0.8235204 ops/s 1.214299 s/op x0.785 48 runs 60.2 s ✔ migrate state 1500000 validators, 3400 modified, 2000 new 0.6997867 ops/s 1.429007 s/op x0.720 41 runs 60.7 s ✔ naive computeProposerIndex 100000 validators 21.29210 ops/s 46.96578 ms/op x0.591 10 runs 51.8 s getNextSyncCommitteeIndices electra ✔ naiveGetNextSyncCommitteeIndices 1000 validators 0.1319639 ops/s 7.577831 s/op x0.675 8 runs 66.8 s ✔ getNextSyncCommitteeIndices 1000 validators 9.444554 ops/s 105.8811 ms/op x0.753 10 runs 1.60 s ✔ naiveGetNextSyncCommitteeIndices 10000 validators 0.1280431 ops/s 7.809868 s/op x0.766 7 runs 61.8 s ✔ getNextSyncCommitteeIndices 10000 validators 9.244910 ops/s 108.1676 ms/op x0.880 10 runs 1.62 s ✔ naiveGetNextSyncCommitteeIndices 100000 validators 0.1295493 ops/s 7.719071 s/op x0.814 7 runs 61.9 s ✔ getNextSyncCommitteeIndices 100000 validators 9.279165 ops/s 107.7683 ms/op x0.751 10 runs 1.62 s computeShuffledIndex ✔ naive computeShuffledIndex 100000 validators 0.04376956 ops/s 22.84693 s/op x0.719 2 runs 67.8 s ✔ cached computeShuffledIndex 100000 validators 1.790556 ops/s 558.4858 ms/op x0.973 10 runs 6.16 s ✔ naive computeShuffledIndex 2000000 validators 0.002243157 ops/s 445.8003 s/op x0.922 1 runs 931 s ✔ cached computeShuffledIndex 2000000 validators 0.02947726 ops/s 33.92445 s/op x0.810 1 runs 71.3 s packages/state-transition/test/perf/util/signingRoot.test.ts computeSigningRoot ✔ computeSigningRoot for AttestationData 51551.61 ops/s 19.39804 us/op x0.905 491 runs 10.0 s ✔ hash AttestationData serialized data then Buffer.toString(base64 639269.7 ops/s 1.564285 us/op x0.977 5818 runs 10.0 s ✔ toHexString serialized data 886487.9 ops/s 1.128047 us/op x0.926 8417 runs 10.0 s ✔ Buffer.toString(base64) 6071166 ops/s 164.7130 ns/op x0.974 50685 runs 10.1 s ``` --------- Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
77 lines
1.7 KiB
TypeScript
77 lines
1.7 KiB
TypeScript
import {beforeAll, bench, describe} from "@chainsafe/benchmark";
|
|
|
|
/**
|
|
* Enable this if you want to compare performance of Buffer vs Uint8Array operations. Not lodestar code so skipped by default.
|
|
*/
|
|
describe.skip("bytes utils", () => {
|
|
const roots: Uint8Array[] = [];
|
|
let buffers: Buffer[] = [];
|
|
const count = 32;
|
|
|
|
beforeAll(() => {
|
|
for (let i = 0; i < count; i++) {
|
|
roots.push(new Uint8Array(Array.from({length: 32}, () => i)));
|
|
}
|
|
buffers = roots.map((root) => Buffer.from(root.buffer));
|
|
}, 60 * 1000);
|
|
|
|
bench({
|
|
id: `Buffer.concat ${count} items`,
|
|
fn: () => {
|
|
Buffer.concat(buffers);
|
|
},
|
|
});
|
|
|
|
bench({
|
|
id: `Uint8Array.set ${count} items`,
|
|
fn: () => {
|
|
let size = 0;
|
|
for (const b of buffers) {
|
|
size += b.length;
|
|
}
|
|
const arr = new Uint8Array(size);
|
|
let offset = 0;
|
|
for (const b of buffers) {
|
|
arr.set(b, offset);
|
|
offset += b.length;
|
|
}
|
|
},
|
|
});
|
|
|
|
bench({
|
|
id: "Buffer.copy",
|
|
fn: () => {
|
|
const arr = Buffer.alloc(32 * count);
|
|
let offset = 0;
|
|
for (const b of buffers) {
|
|
b.copy(arr, offset, 0, b.length);
|
|
offset += b.length;
|
|
}
|
|
},
|
|
});
|
|
|
|
bench({
|
|
id: "Uint8Array.set - with subarray",
|
|
fn: () => {
|
|
const arr = new Uint8Array(32 * count);
|
|
let offset = 0;
|
|
for (const b of roots) {
|
|
arr.set(b.subarray(0, b.length), offset);
|
|
offset += b.length;
|
|
}
|
|
},
|
|
});
|
|
|
|
bench({
|
|
id: "Uint8Array.set - without subarray",
|
|
fn: () => {
|
|
const arr = new Uint8Array(32 * count);
|
|
let offset = 0;
|
|
for (const b of roots) {
|
|
arr.set(b, offset);
|
|
offset += b.length;
|
|
}
|
|
},
|
|
});
|
|
});
|