Skip to content

Commit

Permalink
fix: avoid Buffer.from copies (#6723)
Browse files Browse the repository at this point in the history
* fix: avoid Buffer.from copies

* chore: simplify shuffling

* fix: use subarray instead of slice in shuffling

* chore: remove unnecessary devDependencies

* chore: rely on fastify 4.x behavior

* chore: avoid copy in verifyMerkleBranch

* use toBase64

* relax assertions in shuffle function

* Update packages/state-transition/src/util/shuffle.ts

Co-authored-by: twoeths <tuyen@chainsafe.io>

---------

Co-authored-by: twoeths <tuyen@chainsafe.io>
  • Loading branch information
wemeetagain and twoeths authored May 24, 2024
1 parent 66fe753 commit 1831d47
Show file tree
Hide file tree
Showing 20 changed files with 91 additions and 60 deletions.
8 changes: 4 additions & 4 deletions packages/api/src/beacon/server/beacon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerR
handler: async (req) => {
const response = await api.getBlock(...reqSerializers.getBlock.parseReq(req));
if (response instanceof Uint8Array) {
// Fastify 3.x.x will automatically add header `Content-Type: application/octet-stream` if Buffer
return Buffer.from(response);
// Fastify 4.x.x will automatically add header `Content-Type: application/octet-stream` if TypedArray
return response;
} else {
return returnTypes.getBlock.toJson(response);
}
Expand All @@ -37,8 +37,8 @@ export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerR
const slot = extractSlotFromBlockBytes(response);
const version = config.getForkName(slot);
void res.header("Eth-Consensus-Version", version);
// Fastify 3.x.x will automatically add header `Content-Type: application/octet-stream` if Buffer
return Buffer.from(response);
// Fastify 4.x.x will automatically add header `Content-Type: application/octet-stream` if TypedArray
return response;
} else {
void res.header("Eth-Consensus-Version", response.version);
return returnTypes.getBlockV2.toJson(response);
Expand Down
8 changes: 4 additions & 4 deletions packages/api/src/beacon/server/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerR
handler: async (req) => {
const response = await api.getState(...reqSerializers.getState.parseReq(req));
if (response instanceof Uint8Array) {
// Fastify 3.x.x will automatically add header `Content-Type: application/octet-stream` if Buffer
return Buffer.from(response);
// Fastify 4.x.x will automatically add header `Content-Type: application/octet-stream` if TypedArray
return response;
} else {
return returnTypes.getState.toJson(response);
}
Expand All @@ -38,8 +38,8 @@ export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerR
const slot = extractSlotFromStateBytes(response);
const version = config.getForkName(slot);
void res.header("Eth-Consensus-Version", version);
// Fastify 3.x.x will automatically add header `Content-Type: application/octet-stream` if Buffer
return Buffer.from(response.buffer, response.byteOffset, response.byteLength);
// Fastify 4.x.x will automatically add header `Content-Type: application/octet-stream` if TypedArray
return response;
} else {
void res.header("Eth-Consensus-Version", response.version);
return returnTypes.getStateV2.toJson(response);
Expand Down
8 changes: 4 additions & 4 deletions packages/api/src/beacon/server/proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerR
for (let i = 0; i < leaves.length; i++) {
response.set(leaves[i], i * 32);
}
// Fastify 3.x.x will automatically add header `Content-Type: application/octet-stream` if Buffer
return Buffer.from(response);
// Fastify 4.x.x will automatically add header `Content-Type: application/octet-stream` if TypedArray
return response;
},
},
getBlockProof: {
Expand All @@ -38,8 +38,8 @@ export function getRoutes(config: ChainForkConfig, api: ServerApi<Api>): ServerR
for (let i = 0; i < leaves.length; i++) {
response.set(leaves[i], i * 32);
}
// Fastify 3.x.x will automatically add header `Content-Type: application/octet-stream` if Buffer
return Buffer.from(response);
// Fastify 4.x.x will automatically add header `Content-Type: application/octet-stream` if TypedArray
return response;
},
},
};
Expand Down
2 changes: 1 addition & 1 deletion packages/beacon-node/src/network/gossip/encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function msgIdFn(gossipTopicCache: GossipTopicCache, msg: Message): Uint8
vec = [MESSAGE_DOMAIN_VALID_SNAPPY, intToBytes(msg.topic.length, 8), Buffer.from(msg.topic), msg.data];
}

return Buffer.from(digest(Buffer.concat(vec))).subarray(0, 20);
return digest(Buffer.concat(vec)).subarray(0, 20);
}

export class DataTransformSnappy {
Expand Down
12 changes: 7 additions & 5 deletions packages/beacon-node/src/util/sszBytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ export function getAttDataBase64FromAttestationSerialized(data: Uint8Array): Att
}

// base64 is a bit efficient than hex
return Buffer.from(data.slice(VARIABLE_FIELD_OFFSET, VARIABLE_FIELD_OFFSET + ATTESTATION_DATA_SIZE)).toString(
"base64"
);
return toBase64(data.slice(VARIABLE_FIELD_OFFSET, VARIABLE_FIELD_OFFSET + ATTESTATION_DATA_SIZE));
}

/**
Expand Down Expand Up @@ -150,9 +148,9 @@ export function getAttDataBase64FromSignedAggregateAndProofSerialized(data: Uint
}

// base64 is a bit efficient than hex
return Buffer.from(
return toBase64(
data.slice(SIGNED_AGGREGATE_AND_PROOF_SLOT_OFFSET, SIGNED_AGGREGATE_AND_PROOF_SLOT_OFFSET + ATTESTATION_DATA_SIZE)
).toString("base64");
);
}

/**
Expand Down Expand Up @@ -206,3 +204,7 @@ function getSlotFromOffset(data: Uint8Array, offset: number): Slot {
// Read only the first 4 bytes of Slot, max value is 4,294,967,295 will be reached 1634 years after genesis
return dv.getUint32(offset, true);
}

function toBase64(data: Uint8Array): string {
return Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString("base64");
}
36 changes: 36 additions & 0 deletions packages/beacon-node/test/perf/util/bytes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,40 @@ describe("bytes utils", function () {
}
},
});

itBench({
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;
}
},
});

itBench({
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;
}
},
});

itBench({
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;
}
},
});
});
4 changes: 3 additions & 1 deletion packages/reqresp/src/encoders/responseEncode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {encodeErrorMessage} from "../utils/index.js";
import {ContextBytesType, ContextBytesFactory, MixedProtocol, Protocol, ResponseOutgoing} from "../types.js";
import {RespStatus, RpcResponseStatusError} from "../interface.js";

const SUCCESS_BUFFER = Buffer.from([RespStatus.SUCCESS]);

/**
* Yields byte chunks for a `<response>` with a zero response code `<result>`
* ```bnf
Expand All @@ -24,7 +26,7 @@ export function responseEncodeSuccess(
cbs.onChunk(chunkIndex++);

// <result>
yield Buffer.from([RespStatus.SUCCESS]);
yield SUCCESS_BUFFER;

// <context-bytes> - from altair
const contextBytes = getContextBytes(protocol.contextBytes, chunk);
Expand Down
3 changes: 2 additions & 1 deletion packages/reqresp/src/encodingStrategies/sszSnappy/encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const writeSszSnappyPayload = encodeSszSnappy as (bytes: Uint8Array) => A
*/
export async function* encodeSszSnappy(bytes: Buffer): AsyncGenerator<Buffer> {
// MUST encode the length of the raw SSZ bytes, encoded as an unsigned protobuf varint
yield Buffer.from(varintEncode(bytes.length));
const varint = varintEncode(bytes.length);
yield Buffer.from(varint.buffer, varint.byteOffset, varint.byteLength);

// By first computing and writing the SSZ byte length, the SSZ encoder can then directly
// write the chunk contents to the stream. Snappy writer compresses frame by frame
Expand Down
6 changes: 3 additions & 3 deletions packages/reqresp/src/utils/errorMessage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {encodeSszSnappy} from "../encodingStrategies/sszSnappy/encode.js";
import {writeSszSnappyPayload} from "../encodingStrategies/sszSnappy/encode.js";
import {Encoding} from "../types.js";

// ErrorMessage schema:
Expand All @@ -17,11 +17,11 @@ import {Encoding} from "../types.js";
*/
export async function* encodeErrorMessage(errorMessage: string, encoding: Encoding): AsyncGenerator<Buffer> {
const encoder = new TextEncoder();
const bytes = Buffer.from(encoder.encode(errorMessage).slice(0, 256));
const bytes = encoder.encode(errorMessage).slice(0, 256);

switch (encoding) {
case Encoding.SSZ_SNAPPY:
yield* encodeSszSnappy(bytes);
yield* writeSszSnappyPayload(bytes);
}
}

Expand Down
6 changes: 1 addition & 5 deletions packages/state-transition/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@
"@lodestar/params": "^1.18.1",
"@lodestar/types": "^1.18.1",
"@lodestar/utils": "^1.18.1",
"bigint-buffer": "^1.1.5",
"buffer-xor": "^2.0.2"
},
"devDependencies": {
"@types/buffer-xor": "^2.0.0"
"bigint-buffer": "^1.1.5"
},
"keywords": [
"ethereum",
Expand Down
11 changes: 9 additions & 2 deletions packages/state-transition/src/block/processRandao.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import xor from "buffer-xor";
import {digest} from "@chainsafe/as-sha256";
import {allForks} from "@lodestar/types";
import {EPOCHS_PER_HISTORICAL_VECTOR} from "@lodestar/params";
Expand Down Expand Up @@ -28,6 +27,14 @@ export function processRandao(
}

// mix in RANDAO reveal
const randaoMix = xor(Buffer.from(getRandaoMix(state, epoch)), Buffer.from(digest(randaoReveal)));
const randaoMix = xor(getRandaoMix(state, epoch), digest(randaoReveal));
state.randaoMixes.set(epoch % EPOCHS_PER_HISTORICAL_VECTOR, randaoMix);
}

function xor(a: Uint8Array, b: Uint8Array): Uint8Array {
const length = Math.min(a.length, b.length);
for (let i = 0; i < length; i++) {
a[i] = a[i] ^ b[i];
}
return a;
}
2 changes: 1 addition & 1 deletion packages/state-transition/src/cache/pubkeyCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function toMemoryEfficientHexStr(hex: Uint8Array | string): string {
return hex;
}

return Buffer.from(hex).toString("hex");
return Buffer.from(hex.buffer, hex.byteOffset, hex.byteLength).toString("hex");
}

export class PubkeyIndexMap {
Expand Down
9 changes: 5 additions & 4 deletions packages/state-transition/src/util/shuffle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ function innerShuffleList(input: Shuffleable, seed: Bytes32, dir: boolean): void
const listSize = input.length >>> 0;
// check if list size fits in uint32
assert.equal(listSize, input.length, "input length does not fit uint32");
// check that the seed is 32 bytes
assert.lte(seed.length, _SHUFFLE_H_SEED_SIZE, `seed length is not lte ${_SHUFFLE_H_SEED_SIZE} bytes`);

const buf = Buffer.alloc(_SHUFFLE_H_TOTAL_SIZE);
let r = 0;
Expand All @@ -100,8 +102,7 @@ function innerShuffleList(input: Shuffleable, seed: Bytes32, dir: boolean): void
}

// Seed is always the first 32 bytes of the hash input, we never have to change this part of the buffer.
const _seed = seed;
Buffer.from(_seed).copy(buf, 0, 0, _SHUFFLE_H_SEED_SIZE);
buf.set(seed, 0);

// initial values here are not used: overwritten first within the inner for loop.
let source = seed; // just setting it to a Bytes32
Expand All @@ -114,8 +115,8 @@ function innerShuffleList(input: Shuffleable, seed: Bytes32, dir: boolean): void
buf[_SHUFFLE_H_SEED_SIZE] = r;
// Seed is already in place, now just hash the correct part of the buffer, and take a uint64 from it,
// and modulo it to get a pivot within range.
const h = digest(buf.slice(0, _SHUFFLE_H_PIVOT_VIEW_SIZE));
const pivot = Number(bytesToBigInt(h.slice(0, 8)) % BigInt(listSize)) >>> 0;
const h = digest(buf.subarray(0, _SHUFFLE_H_PIVOT_VIEW_SIZE));
const pivot = Number(bytesToBigInt(h.subarray(0, 8)) % BigInt(listSize)) >>> 0;

// Split up the for-loop in two:
// 1. Handle the part from 0 (incl) to pivot (incl). This is mirrored around (pivot / 2)
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/verifyMerkleBranch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ export function verifyMerkleBranch(
value = digest64(Buffer.concat([value, proof[i]]));
}
}
return Buffer.from(value).equals(root);
return Buffer.from(value.buffer, value.byteOffset, value.byteLength).equals(root);
}
4 changes: 2 additions & 2 deletions packages/validator/src/repositories/metaDataRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class MetaDataRepository {
}

async setGenesisValidatorsRoot(genesisValidatorsRoot: Root): Promise<void> {
await this.db.put(this.encodeKey(GENESIS_VALIDATORS_ROOT), Buffer.from(genesisValidatorsRoot), this.dbReqOpts);
await this.db.put(this.encodeKey(GENESIS_VALIDATORS_ROOT), genesisValidatorsRoot, this.dbReqOpts);
}

async getGenesisTime(): Promise<UintNum64 | null> {
Expand All @@ -34,7 +34,7 @@ export class MetaDataRepository {
}

async setGenesisTime(genesisTime: UintNum64): Promise<void> {
await this.db.put(this.encodeKey(GENESIS_TIME), Buffer.from(ssz.UintNum64.serialize(genesisTime)), this.dbReqOpts);
await this.db.put(this.encodeKey(GENESIS_TIME), ssz.UintNum64.serialize(genesisTime), this.dbReqOpts);
}

private encodeKey(key: Uint8Array): Uint8Array {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class AttestationByTargetRepository {
await this.db.batchPut(
atts.map((att) => ({
key: this.encodeKey(pubkey, att.targetEpoch),
value: Buffer.from(this.type.serialize(att)),
value: this.type.serialize(att),
})),
this.dbReqOpts
);
Expand All @@ -62,7 +62,7 @@ export class AttestationByTargetRepository {
}

private encodeKey(pubkey: BLSPubkey, targetEpoch: Epoch): Uint8Array {
return encodeKey(this.bucket, Buffer.concat([Buffer.from(pubkey), intToBytes(BigInt(targetEpoch), uintLen, "be")]));
return encodeKey(this.bucket, Buffer.concat([pubkey, intToBytes(BigInt(targetEpoch), uintLen, "be")]));
}

private decodeKey(key: Uint8Array): {pubkey: BLSPubkey; targetEpoch: Epoch} {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ export class AttestationLowerBoundRepository {
}

async set(pubkey: BLSPubkey, value: SlashingProtectionLowerBound): Promise<void> {
await this.db.put(this.encodeKey(pubkey), Buffer.from(this.type.serialize(value)), this.dbReqOpts);
await this.db.put(this.encodeKey(pubkey), this.type.serialize(value), this.dbReqOpts);
}

private encodeKey(pubkey: BLSPubkey): Uint8Array {
return encodeKey(this.bucket, Buffer.from(pubkey));
return encodeKey(this.bucket, pubkey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class BlockBySlotRepository {
await this.db.batchPut(
blocks.map((block) => ({
key: this.encodeKey(pubkey, block.slot),
value: Buffer.from(this.type.serialize(block)),
value: this.type.serialize(block),
})),
this.dbReqOpts
);
Expand All @@ -66,7 +66,7 @@ export class BlockBySlotRepository {
}

private encodeKey(pubkey: BLSPubkey, slot: Slot): Uint8Array {
return encodeKey(this.bucket, Buffer.concat([Buffer.from(pubkey), intToBytes(BigInt(slot), uintLen, "be")]));
return encodeKey(this.bucket, Buffer.concat([pubkey, intToBytes(BigInt(slot), uintLen, "be")]));
}

private decodeKey(key: Uint8Array): {pubkey: BLSPubkey; slot: Slot} {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ class SpanDistanceRepository {
await this.db.batchPut(
values.map((value) => ({
key: this.encodeKey(pubkey, value.source),
value: Buffer.from(this.type.serialize(value.distance)),
value: this.type.serialize(value.distance),
})),
this.dbReqOpts
);
}

private encodeKey(pubkey: BLSPubkey, epoch: Epoch): Uint8Array {
return encodeKey(this.bucket, Buffer.concat([Buffer.from(pubkey), intToBytes(BigInt(epoch), 8, "be")]));
return encodeKey(this.bucket, Buffer.concat([pubkey, intToBytes(BigInt(epoch), 8, "be")]));
}
}
14 changes: 0 additions & 14 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2831,13 +2831,6 @@
resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9"
integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==

"@types/buffer-xor@^2.0.0":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/buffer-xor/-/buffer-xor-2.0.2.tgz#d8c463583b8fbb322ea824562dc78a0c3cea2ca6"
integrity sha512-OqdCua7QCTupPnJgmyGJUpxWgbuOi0IMIVslXTSePS2o+qDrDB6f2Pg44zRyqhUA5GbFAf39U8z0+mH4WG0fLQ==
dependencies:
"@types/node" "*"

"@types/cacheable-request@^6.0.1":
version "6.0.3"
resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183"
Expand Down Expand Up @@ -4436,13 +4429,6 @@ buffer-xor@^1.0.3:
resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz"
integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=

buffer-xor@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz"
integrity sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==
dependencies:
safe-buffer "^5.1.1"

buffer@4.9.2, buffer@^4.3.0:
version "4.9.2"
resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz"
Expand Down

1 comment on commit 1831d47

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ 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: 1831d47 Previous: 95ce044 Ratio
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 5.3494 ms/op 1.2232 ms/op 4.37
Full benchmark results
Benchmark suite Current: 1831d47 Previous: 95ce044 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.0257 ms/op 933.55 us/op 1.10
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 91.813 us/op 68.400 us/op 1.34
BLS verify - blst-native 1.1944 ms/op 1.1353 ms/op 1.05
BLS verifyMultipleSignatures 3 - blst-native 2.5098 ms/op 2.2036 ms/op 1.14
BLS verifyMultipleSignatures 8 - blst-native 5.5071 ms/op 4.7314 ms/op 1.16
BLS verifyMultipleSignatures 32 - blst-native 20.004 ms/op 18.048 ms/op 1.11
BLS verifyMultipleSignatures 64 - blst-native 39.836 ms/op 34.439 ms/op 1.16
BLS verifyMultipleSignatures 128 - blst-native 77.788 ms/op 67.997 ms/op 1.14
BLS deserializing 10000 signatures 890.53 ms/op 809.90 ms/op 1.10
BLS deserializing 100000 signatures 8.9152 s/op 8.1736 s/op 1.09
BLS verifyMultipleSignatures - same message - 3 - blst-native 1.2771 ms/op 1.1622 ms/op 1.10
BLS verifyMultipleSignatures - same message - 8 - blst-native 1.4502 ms/op 1.2877 ms/op 1.13
BLS verifyMultipleSignatures - same message - 32 - blst-native 2.2828 ms/op 2.0240 ms/op 1.13
BLS verifyMultipleSignatures - same message - 64 - blst-native 3.3959 ms/op 3.0193 ms/op 1.12
BLS verifyMultipleSignatures - same message - 128 - blst-native 5.6055 ms/op 4.9662 ms/op 1.13
BLS aggregatePubkeys 32 - blst-native 28.328 us/op 25.203 us/op 1.12
BLS aggregatePubkeys 128 - blst-native 110.16 us/op 95.715 us/op 1.15
notSeenSlots=1 numMissedVotes=1 numBadVotes=10 63.617 ms/op 47.724 ms/op 1.33
notSeenSlots=1 numMissedVotes=0 numBadVotes=4 51.832 ms/op 38.568 ms/op 1.34
notSeenSlots=2 numMissedVotes=1 numBadVotes=10 31.658 ms/op 36.910 ms/op 0.86
getSlashingsAndExits - default max 206.36 us/op 203.36 us/op 1.01
getSlashingsAndExits - 2k 526.77 us/op 390.06 us/op 1.35
proposeBlockBody type=full, size=empty 5.6800 ms/op 5.5383 ms/op 1.03
isKnown best case - 1 super set check 469.00 ns/op 667.00 ns/op 0.70
isKnown normal case - 2 super set checks 401.00 ns/op 642.00 ns/op 0.62
isKnown worse case - 16 super set checks 403.00 ns/op 643.00 ns/op 0.63
InMemoryCheckpointStateCache - add get delete 6.4700 us/op 8.3540 us/op 0.77
validate api signedAggregateAndProof - struct 2.5282 ms/op 2.0093 ms/op 1.26
validate gossip signedAggregateAndProof - struct 2.5318 ms/op 2.0311 ms/op 1.25
validate gossip attestation - vc 640000 1.2302 ms/op 1.1334 ms/op 1.09
batch validate gossip attestation - vc 640000 - chunk 32 169.82 us/op 147.52 us/op 1.15
batch validate gossip attestation - vc 640000 - chunk 64 154.43 us/op 130.86 us/op 1.18
batch validate gossip attestation - vc 640000 - chunk 128 147.94 us/op 124.59 us/op 1.19
batch validate gossip attestation - vc 640000 - chunk 256 138.31 us/op 114.86 us/op 1.20
pickEth1Vote - no votes 1.3061 ms/op 876.71 us/op 1.49
pickEth1Vote - max votes 7.5759 ms/op 8.6771 ms/op 0.87
pickEth1Vote - Eth1Data hashTreeRoot value x2048 17.163 ms/op 14.971 ms/op 1.15
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 18.817 ms/op 23.169 ms/op 0.81
pickEth1Vote - Eth1Data fastSerialize value x2048 629.05 us/op 410.90 us/op 1.53
pickEth1Vote - Eth1Data fastSerialize tree x2048 4.0735 ms/op 4.7140 ms/op 0.86
bytes32 toHexString 454.00 ns/op 591.00 ns/op 0.77
bytes32 Buffer.toString(hex) 280.00 ns/op 462.00 ns/op 0.61
bytes32 Buffer.toString(hex) from Uint8Array 410.00 ns/op 594.00 ns/op 0.69
bytes32 Buffer.toString(hex) + 0x 282.00 ns/op 454.00 ns/op 0.62
Object access 1 prop 0.16000 ns/op 0.32300 ns/op 0.50
Map access 1 prop 0.14400 ns/op 0.31100 ns/op 0.46
Object get x1000 7.3090 ns/op 5.0070 ns/op 1.46
Map get x1000 0.82900 ns/op 0.88200 ns/op 0.94
Object set x1000 46.375 ns/op 26.278 ns/op 1.76
Map set x1000 26.952 ns/op 17.754 ns/op 1.52
Return object 10000 times 0.25260 ns/op 0.22900 ns/op 1.10
Throw Error 10000 times 3.5376 us/op 2.5931 us/op 1.36
fastMsgIdFn sha256 / 200 bytes 2.4420 us/op 2.0050 us/op 1.22
fastMsgIdFn h32 xxhash / 200 bytes 316.00 ns/op 423.00 ns/op 0.75
fastMsgIdFn h64 xxhash / 200 bytes 365.00 ns/op 467.00 ns/op 0.78
fastMsgIdFn sha256 / 1000 bytes 7.7160 us/op 5.9520 us/op 1.30
fastMsgIdFn h32 xxhash / 1000 bytes 452.00 ns/op 530.00 ns/op 0.85
fastMsgIdFn h64 xxhash / 1000 bytes 439.00 ns/op 528.00 ns/op 0.83
fastMsgIdFn sha256 / 10000 bytes 66.973 us/op 50.133 us/op 1.34
fastMsgIdFn h32 xxhash / 10000 bytes 1.9620 us/op 1.8720 us/op 1.05
fastMsgIdFn h64 xxhash / 10000 bytes 1.3320 us/op 1.3450 us/op 0.99
send data - 1000 256B messages 15.178 ms/op 11.263 ms/op 1.35
send data - 1000 512B messages 19.989 ms/op 13.547 ms/op 1.48
send data - 1000 1024B messages 27.936 ms/op 21.182 ms/op 1.32
send data - 1000 1200B messages 21.489 ms/op 23.629 ms/op 0.91
send data - 1000 2048B messages 38.635 ms/op 30.360 ms/op 1.27
send data - 1000 4096B messages 38.485 ms/op 27.404 ms/op 1.40
send data - 1000 16384B messages 84.417 ms/op 69.336 ms/op 1.22
send data - 1000 65536B messages 322.70 ms/op 279.57 ms/op 1.15
enrSubnets - fastDeserialize 64 bits 1.2680 us/op 1.0920 us/op 1.16
enrSubnets - ssz BitVector 64 bits 513.00 ns/op 557.00 ns/op 0.92
enrSubnets - fastDeserialize 4 bits 204.00 ns/op 322.00 ns/op 0.63
enrSubnets - ssz BitVector 4 bits 506.00 ns/op 556.00 ns/op 0.91
prioritizePeers score -10:0 att 32-0.1 sync 2-0 202.45 us/op 148.72 us/op 1.36
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 257.98 us/op 195.89 us/op 1.32
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 340.46 us/op 223.69 us/op 1.52
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 519.15 us/op 375.70 us/op 1.38
prioritizePeers score 0:0 att 64-1 sync 4-1 620.46 us/op 437.38 us/op 1.42
array of 16000 items push then shift 1.7221 us/op 1.3091 us/op 1.32
LinkedList of 16000 items push then shift 8.4480 ns/op 6.0850 ns/op 1.39
array of 16000 items push then pop 143.64 ns/op 90.811 ns/op 1.58
LinkedList of 16000 items push then pop 7.4310 ns/op 6.0110 ns/op 1.24
array of 24000 items push then shift 2.7020 us/op 1.9852 us/op 1.36
LinkedList of 24000 items push then shift 7.5680 ns/op 6.1410 ns/op 1.23
array of 24000 items push then pop 178.29 ns/op 124.78 ns/op 1.43
LinkedList of 24000 items push then pop 6.7180 ns/op 5.9720 ns/op 1.12
intersect bitArray bitLen 8 6.0160 ns/op 5.2960 ns/op 1.14
intersect array and set length 8 57.157 ns/op 48.593 ns/op 1.18
intersect bitArray bitLen 128 36.208 ns/op 29.571 ns/op 1.22
intersect array and set length 128 811.92 ns/op 681.86 ns/op 1.19
bitArray.getTrueBitIndexes() bitLen 128 1.3180 us/op 1.3580 us/op 0.97
bitArray.getTrueBitIndexes() bitLen 248 2.0960 us/op 2.0690 us/op 1.01
bitArray.getTrueBitIndexes() bitLen 512 4.1650 us/op 3.7430 us/op 1.11
Buffer.concat 32 items 860.00 ns/op 1.0230 us/op 0.84
Uint8Array.set 32 items 1.7580 us/op 1.6310 us/op 1.08
Buffer.copy 1.9350 us/op
Uint8Array.set - with subarray 2.4580 us/op
Uint8Array.set - without subarray 1.7020 us/op
Set add up to 64 items then delete first 2.4258 us/op 1.7949 us/op 1.35
OrderedSet add up to 64 items then delete first 3.3601 us/op 2.7578 us/op 1.22
Set add up to 64 items then delete last 2.5285 us/op 2.0535 us/op 1.23
OrderedSet add up to 64 items then delete last 3.7789 us/op 3.1094 us/op 1.22
Set add up to 64 items then delete middle 2.6221 us/op 2.0412 us/op 1.28
OrderedSet add up to 64 items then delete middle 4.8645 us/op 4.2191 us/op 1.15
Set add up to 128 items then delete first 5.2343 us/op 4.0645 us/op 1.29
OrderedSet add up to 128 items then delete first 8.4389 us/op 6.3470 us/op 1.33
Set add up to 128 items then delete last 6.4213 us/op 4.0704 us/op 1.58
OrderedSet add up to 128 items then delete last 11.490 us/op 5.6515 us/op 2.03
Set add up to 128 items then delete middle 7.3960 us/op 3.6329 us/op 2.04
OrderedSet add up to 128 items then delete middle 17.591 us/op 10.394 us/op 1.69
Set add up to 256 items then delete first 16.320 us/op 7.3421 us/op 2.22
OrderedSet add up to 256 items then delete first 25.965 us/op 12.814 us/op 2.03
Set add up to 256 items then delete last 17.377 us/op 8.9208 us/op 1.95
OrderedSet add up to 256 items then delete last 26.055 us/op 14.739 us/op 1.77
Set add up to 256 items then delete middle 12.880 us/op 7.8054 us/op 1.65
OrderedSet add up to 256 items then delete middle 45.374 us/op 36.154 us/op 1.25
transfer serialized Status (84 B) 1.9850 us/op 1.8550 us/op 1.07
copy serialized Status (84 B) 1.3290 us/op 1.4940 us/op 0.89
transfer serialized SignedVoluntaryExit (112 B) 2.0340 us/op 1.9340 us/op 1.05
copy serialized SignedVoluntaryExit (112 B) 1.6760 us/op 1.5200 us/op 1.10
transfer serialized ProposerSlashing (416 B) 2.4480 us/op 2.4010 us/op 1.02
copy serialized ProposerSlashing (416 B) 2.1600 us/op 2.0250 us/op 1.07
transfer serialized Attestation (485 B) 2.9640 us/op 2.2210 us/op 1.33
copy serialized Attestation (485 B) 1.9820 us/op 2.0280 us/op 0.98
transfer serialized AttesterSlashing (33232 B) 2.3240 us/op 2.2780 us/op 1.02
copy serialized AttesterSlashing (33232 B) 11.485 us/op 7.8580 us/op 1.46
transfer serialized Small SignedBeaconBlock (128000 B) 3.1210 us/op 2.9800 us/op 1.05
copy serialized Small SignedBeaconBlock (128000 B) 36.542 us/op 34.940 us/op 1.05
transfer serialized Avg SignedBeaconBlock (200000 B) 4.0810 us/op 3.5540 us/op 1.15
copy serialized Avg SignedBeaconBlock (200000 B) 51.741 us/op 57.139 us/op 0.91
transfer serialized BlobsSidecar (524380 B) 5.3190 us/op 5.3390 us/op 1.00
copy serialized BlobsSidecar (524380 B) 170.88 us/op 148.37 us/op 1.15
transfer serialized Big SignedBeaconBlock (1000000 B) 5.5620 us/op 4.6480 us/op 1.20
copy serialized Big SignedBeaconBlock (1000000 B) 391.14 us/op 309.19 us/op 1.27
pass gossip attestations to forkchoice per slot 3.5228 ms/op 3.3913 ms/op 1.04
forkChoice updateHead vc 100000 bc 64 eq 0 577.32 us/op 508.00 us/op 1.14
forkChoice updateHead vc 600000 bc 64 eq 0 5.9359 ms/op 4.3063 ms/op 1.38
forkChoice updateHead vc 1000000 bc 64 eq 0 7.2292 ms/op 5.7017 ms/op 1.27
forkChoice updateHead vc 600000 bc 320 eq 0 3.9336 ms/op 3.3869 ms/op 1.16
forkChoice updateHead vc 600000 bc 1200 eq 0 4.3957 ms/op 3.4448 ms/op 1.28
forkChoice updateHead vc 600000 bc 7200 eq 0 5.9561 ms/op 4.1135 ms/op 1.45
forkChoice updateHead vc 600000 bc 64 eq 1000 11.262 ms/op 10.783 ms/op 1.04
forkChoice updateHead vc 600000 bc 64 eq 10000 11.498 ms/op 11.287 ms/op 1.02
forkChoice updateHead vc 600000 bc 64 eq 300000 27.811 ms/op 42.356 ms/op 0.66
computeDeltas 500000 validators 300 proto nodes 4.7317 ms/op 3.9934 ms/op 1.18
computeDeltas 500000 validators 1200 proto nodes 4.4011 ms/op 3.9173 ms/op 1.12
computeDeltas 500000 validators 7200 proto nodes 4.3780 ms/op 3.7280 ms/op 1.17
computeDeltas 750000 validators 300 proto nodes 5.8905 ms/op 5.8149 ms/op 1.01
computeDeltas 750000 validators 1200 proto nodes 6.2860 ms/op 6.4169 ms/op 0.98
computeDeltas 750000 validators 7200 proto nodes 5.7938 ms/op 5.7637 ms/op 1.01
computeDeltas 1400000 validators 300 proto nodes 10.666 ms/op 11.176 ms/op 0.95
computeDeltas 1400000 validators 1200 proto nodes 10.422 ms/op 11.797 ms/op 0.88
computeDeltas 1400000 validators 7200 proto nodes 9.8196 ms/op 12.708 ms/op 0.77
computeDeltas 2100000 validators 300 proto nodes 14.477 ms/op 15.833 ms/op 0.91
computeDeltas 2100000 validators 1200 proto nodes 14.634 ms/op 16.412 ms/op 0.89
computeDeltas 2100000 validators 7200 proto nodes 15.341 ms/op 15.906 ms/op 0.96
altair processAttestation - 250000 vs - 7PWei normalcase 1.8005 ms/op 1.7294 ms/op 1.04
altair processAttestation - 250000 vs - 7PWei worstcase 3.3565 ms/op 2.7068 ms/op 1.24
altair processAttestation - setStatus - 1/6 committees join 138.49 us/op 138.28 us/op 1.00
altair processAttestation - setStatus - 1/3 committees join 279.08 us/op 264.40 us/op 1.06
altair processAttestation - setStatus - 1/2 committees join 403.35 us/op 387.66 us/op 1.04
altair processAttestation - setStatus - 2/3 committees join 478.24 us/op 451.97 us/op 1.06
altair processAttestation - setStatus - 4/5 committees join 663.75 us/op 602.82 us/op 1.10
altair processAttestation - setStatus - 100% committees join 828.05 us/op 812.61 us/op 1.02
altair processBlock - 250000 vs - 7PWei normalcase 9.1828 ms/op 10.263 ms/op 0.89
altair processBlock - 250000 vs - 7PWei normalcase hashState 38.930 ms/op 41.183 ms/op 0.95
altair processBlock - 250000 vs - 7PWei worstcase 33.732 ms/op 34.517 ms/op 0.98
altair processBlock - 250000 vs - 7PWei worstcase hashState 99.842 ms/op 98.026 ms/op 1.02
phase0 processBlock - 250000 vs - 7PWei normalcase 2.8316 ms/op 3.0351 ms/op 0.93
phase0 processBlock - 250000 vs - 7PWei worstcase 31.345 ms/op 33.834 ms/op 0.93
altair processEth1Data - 250000 vs - 7PWei normalcase 575.72 us/op 670.63 us/op 0.86
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 20.016 us/op 14.889 us/op 1.34
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 78.520 us/op 43.652 us/op 1.80
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 24.386 us/op 23.102 us/op 1.06
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 16.203 us/op 19.744 us/op 0.82
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 232.44 us/op 139.87 us/op 1.66
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 1.4294 ms/op 1.4140 ms/op 1.01
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.6577 ms/op 1.3973 ms/op 1.19
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.6281 ms/op 1.5230 ms/op 1.07
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.4342 ms/op 3.2693 ms/op 1.05
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 3.0323 ms/op 2.1623 ms/op 1.40
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.2436 ms/op 4.6598 ms/op 0.91
Tree 40 250000 create 226.50 ms/op 395.71 ms/op 0.57
Tree 40 250000 get(125000) 151.80 ns/op 149.21 ns/op 1.02
Tree 40 250000 set(125000) 689.21 ns/op 1.3153 us/op 0.52
Tree 40 250000 toArray() 18.327 ms/op 30.081 ms/op 0.61
Tree 40 250000 iterate all - toArray() + loop 16.471 ms/op 28.694 ms/op 0.57
Tree 40 250000 iterate all - get(i) 59.284 ms/op 72.764 ms/op 0.81
MutableVector 250000 create 8.3733 ms/op 11.824 ms/op 0.71
MutableVector 250000 get(125000) 6.8270 ns/op 7.2230 ns/op 0.95
MutableVector 250000 set(125000) 235.54 ns/op 457.97 ns/op 0.51
MutableVector 250000 toArray() 4.1303 ms/op 5.2955 ms/op 0.78
MutableVector 250000 iterate all - toArray() + loop 4.9632 ms/op 5.8304 ms/op 0.85
MutableVector 250000 iterate all - get(i) 1.7527 ms/op 1.4013 ms/op 1.25
Array 250000 create 3.9852 ms/op 5.1650 ms/op 0.77
Array 250000 clone - spread 1.4409 ms/op 1.6866 ms/op 0.85
Array 250000 get(125000) 0.99800 ns/op 1.4440 ns/op 0.69
Array 250000 set(125000) 1.2290 ns/op 1.5290 ns/op 0.80
Array 250000 iterate all - loop 168.16 us/op 170.72 us/op 0.99
effectiveBalanceIncrements clone Uint8Array 300000 33.614 us/op 14.010 us/op 2.40
effectiveBalanceIncrements clone MutableVector 300000 311.00 ns/op 549.00 ns/op 0.57
effectiveBalanceIncrements rw all Uint8Array 300000 202.44 us/op 203.51 us/op 0.99
effectiveBalanceIncrements rw all MutableVector 300000 77.851 ms/op 71.092 ms/op 1.10
phase0 afterProcessEpoch - 250000 vs - 7PWei 92.217 ms/op 84.782 ms/op 1.09
phase0 beforeProcessEpoch - 250000 vs - 7PWei 47.568 ms/op 53.434 ms/op 0.89
altair processEpoch - mainnet_e81889 407.61 ms/op 447.02 ms/op 0.91
mainnet_e81889 - altair beforeProcessEpoch 75.233 ms/op 63.406 ms/op 1.19
mainnet_e81889 - altair processJustificationAndFinalization 17.173 us/op 15.368 us/op 1.12
mainnet_e81889 - altair processInactivityUpdates 5.6221 ms/op 5.1160 ms/op 1.10
mainnet_e81889 - altair processRewardsAndPenalties 40.128 ms/op 61.457 ms/op 0.65
mainnet_e81889 - altair processRegistryUpdates 2.4800 us/op 4.5950 us/op 0.54
mainnet_e81889 - altair processSlashings 477.00 ns/op 1.1160 us/op 0.43
mainnet_e81889 - altair processEth1DataReset 931.00 ns/op 856.00 ns/op 1.09
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.4703 ms/op 1.1215 ms/op 1.31
mainnet_e81889 - altair processSlashingsReset 4.8730 us/op 4.5010 us/op 1.08
mainnet_e81889 - altair processRandaoMixesReset 6.2030 us/op 5.7800 us/op 1.07
mainnet_e81889 - altair processHistoricalRootsUpdate 983.00 ns/op 1.0370 us/op 0.95
mainnet_e81889 - altair processParticipationFlagUpdates 2.2730 us/op 1.8370 us/op 1.24
mainnet_e81889 - altair processSyncCommitteeUpdates 1.0150 us/op 908.00 ns/op 1.12
mainnet_e81889 - altair afterProcessEpoch 100.33 ms/op 82.428 ms/op 1.22
capella processEpoch - mainnet_e217614 1.5443 s/op 1.5414 s/op 1.00
mainnet_e217614 - capella beforeProcessEpoch 299.30 ms/op 340.40 ms/op 0.88
mainnet_e217614 - capella processJustificationAndFinalization 18.902 us/op 30.366 us/op 0.62
mainnet_e217614 - capella processInactivityUpdates 17.245 ms/op 19.972 ms/op 0.86
mainnet_e217614 - capella processRewardsAndPenalties 250.60 ms/op 329.14 ms/op 0.76
mainnet_e217614 - capella processRegistryUpdates 31.322 us/op 27.688 us/op 1.13
mainnet_e217614 - capella processSlashings 649.00 ns/op 1.9260 us/op 0.34
mainnet_e217614 - capella processEth1DataReset 430.00 ns/op 1.2240 us/op 0.35
mainnet_e217614 - capella processEffectiveBalanceUpdates 4.3153 ms/op 24.687 ms/op 0.17
mainnet_e217614 - capella processSlashingsReset 3.8000 us/op 7.4090 us/op 0.51
mainnet_e217614 - capella processRandaoMixesReset 6.0340 us/op 10.387 us/op 0.58
mainnet_e217614 - capella processHistoricalRootsUpdate 992.00 ns/op 2.1490 us/op 0.46
mainnet_e217614 - capella processParticipationFlagUpdates 1.9630 us/op 5.8100 us/op 0.34
mainnet_e217614 - capella afterProcessEpoch 275.25 ms/op 335.36 ms/op 0.82
phase0 processEpoch - mainnet_e58758 498.36 ms/op 319.04 ms/op 1.56
mainnet_e58758 - phase0 beforeProcessEpoch 156.95 ms/op 123.74 ms/op 1.27
mainnet_e58758 - phase0 processJustificationAndFinalization 22.245 us/op 18.565 us/op 1.20
mainnet_e58758 - phase0 processRewardsAndPenalties 22.159 ms/op 27.952 ms/op 0.79
mainnet_e58758 - phase0 processRegistryUpdates 13.971 us/op 13.672 us/op 1.02
mainnet_e58758 - phase0 processSlashings 588.00 ns/op 977.00 ns/op 0.60
mainnet_e58758 - phase0 processEth1DataReset 432.00 ns/op 770.00 ns/op 0.56
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.1432 ms/op 1.3942 ms/op 0.82
mainnet_e58758 - phase0 processSlashingsReset 4.0090 us/op 2.9480 us/op 1.36
mainnet_e58758 - phase0 processRandaoMixesReset 4.9280 us/op 6.5970 us/op 0.75
mainnet_e58758 - phase0 processHistoricalRootsUpdate 430.00 ns/op 1.2160 us/op 0.35
mainnet_e58758 - phase0 processParticipationRecordUpdates 4.7500 us/op 7.5580 us/op 0.63
mainnet_e58758 - phase0 afterProcessEpoch 84.735 ms/op 80.511 ms/op 1.05
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.3000 ms/op 1.0517 ms/op 1.24
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 5.3494 ms/op 1.2232 ms/op 4.37
altair processInactivityUpdates - 250000 normalcase 17.397 ms/op 17.763 ms/op 0.98
altair processInactivityUpdates - 250000 worstcase 17.093 ms/op 18.884 ms/op 0.91
phase0 processRegistryUpdates - 250000 normalcase 12.195 us/op 15.017 us/op 0.81
phase0 processRegistryUpdates - 250000 badcase_full_deposits 374.11 us/op 485.11 us/op 0.77
phase0 processRegistryUpdates - 250000 worstcase 0.5 144.93 ms/op 139.83 ms/op 1.04
altair processRewardsAndPenalties - 250000 normalcase 45.625 ms/op 48.610 ms/op 0.94
altair processRewardsAndPenalties - 250000 worstcase 44.668 ms/op 41.498 ms/op 1.08
phase0 getAttestationDeltas - 250000 normalcase 8.6649 ms/op 7.1989 ms/op 1.20
phase0 getAttestationDeltas - 250000 worstcase 9.3644 ms/op 8.3222 ms/op 1.13
phase0 processSlashings - 250000 worstcase 90.393 us/op 92.742 us/op 0.97
altair processSyncCommitteeUpdates - 250000 137.11 ms/op 207.59 ms/op 0.66
BeaconState.hashTreeRoot - No change 484.00 ns/op 1.1900 us/op 0.41
BeaconState.hashTreeRoot - 1 full validator 139.48 us/op 205.84 us/op 0.68
BeaconState.hashTreeRoot - 32 full validator 1.5793 ms/op 1.8437 ms/op 0.86
BeaconState.hashTreeRoot - 512 full validator 14.521 ms/op 19.385 ms/op 0.75
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 154.61 us/op 223.97 us/op 0.69
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.1347 ms/op 3.0530 ms/op 0.70
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 22.629 ms/op 35.174 ms/op 0.64
BeaconState.hashTreeRoot - 1 balances 119.33 us/op 176.85 us/op 0.67
BeaconState.hashTreeRoot - 32 balances 1.3224 ms/op 1.6871 ms/op 0.78
BeaconState.hashTreeRoot - 512 balances 10.348 ms/op 16.584 ms/op 0.62
BeaconState.hashTreeRoot - 250000 balances 188.35 ms/op 245.69 ms/op 0.77
aggregationBits - 2048 els - zipIndexesInBitList 26.606 us/op 26.326 us/op 1.01
byteArrayEquals 32 76.758 ns/op 66.412 ns/op 1.16
Buffer.compare 32 52.083 ns/op 38.889 ns/op 1.34
byteArrayEquals 1024 2.0902 us/op 1.7972 us/op 1.16
Buffer.compare 1024 53.031 ns/op 45.999 ns/op 1.15
byteArrayEquals 16384 33.277 us/op 28.774 us/op 1.16
Buffer.compare 16384 240.68 ns/op 241.84 ns/op 1.00
byteArrayEquals 123687377 258.62 ms/op 218.92 ms/op 1.18
Buffer.compare 123687377 8.5620 ms/op 9.5775 ms/op 0.89
byteArrayEquals 32 - diff last byte 76.409 ns/op 102.92 ns/op 0.74
Buffer.compare 32 - diff last byte 52.859 ns/op 41.088 ns/op 1.29
byteArrayEquals 1024 - diff last byte 2.2269 us/op 1.8049 us/op 1.23
Buffer.compare 1024 - diff last byte 56.932 ns/op 48.450 ns/op 1.18
byteArrayEquals 16384 - diff last byte 33.224 us/op 28.693 us/op 1.16
Buffer.compare 16384 - diff last byte 232.68 ns/op 225.63 ns/op 1.03
byteArrayEquals 123687377 - diff last byte 251.80 ms/op 223.61 ms/op 1.13
Buffer.compare 123687377 - diff last byte 8.0219 ms/op 5.4326 ms/op 1.48
byteArrayEquals 32 - random bytes 5.7060 ns/op 4.7380 ns/op 1.20
Buffer.compare 32 - random bytes 52.205 ns/op 40.184 ns/op 1.30
byteArrayEquals 1024 - random bytes 5.5290 ns/op 4.8860 ns/op 1.13
Buffer.compare 1024 - random bytes 51.235 ns/op 38.568 ns/op 1.33
byteArrayEquals 16384 - random bytes 5.5270 ns/op 4.9280 ns/op 1.12
Buffer.compare 16384 - random bytes 51.360 ns/op 34.560 ns/op 1.49
byteArrayEquals 123687377 - random bytes 8.3900 ns/op 9.0300 ns/op 0.93
Buffer.compare 123687377 - random bytes 55.650 ns/op 42.440 ns/op 1.31
regular array get 100000 times 45.339 us/op 42.154 us/op 1.08
wrappedArray get 100000 times 45.599 us/op 43.001 us/op 1.06
arrayWithProxy get 100000 times 14.268 ms/op 10.615 ms/op 1.34
ssz.Root.equals 57.033 ns/op 58.398 ns/op 0.98
byteArrayEquals 53.686 ns/op 57.553 ns/op 0.93
Buffer.compare 10.997 ns/op 10.628 ns/op 1.03
shuffle list - 16384 els 6.6871 ms/op 6.1113 ms/op 1.09
shuffle list - 250000 els 99.323 ms/op 87.229 ms/op 1.14
processSlot - 1 slots 15.135 us/op 20.928 us/op 0.72
processSlot - 32 slots 3.4792 ms/op 3.6195 ms/op 0.96
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 47.169 ms/op 47.646 ms/op 0.99
getCommitteeAssignments - req 1 vs - 250000 vc 2.6829 ms/op 2.3810 ms/op 1.13
getCommitteeAssignments - req 100 vs - 250000 vc 3.8575 ms/op 3.5044 ms/op 1.10
getCommitteeAssignments - req 1000 vs - 250000 vc 4.2412 ms/op 3.8054 ms/op 1.11
findModifiedValidators - 10000 modified validators 311.01 ms/op 241.31 ms/op 1.29
findModifiedValidators - 1000 modified validators 220.13 ms/op 143.82 ms/op 1.53
findModifiedValidators - 100 modified validators 217.60 ms/op 149.33 ms/op 1.46
findModifiedValidators - 10 modified validators 191.80 ms/op 145.35 ms/op 1.32
findModifiedValidators - 1 modified validators 184.59 ms/op 165.31 ms/op 1.12
findModifiedValidators - no difference 194.63 ms/op 168.38 ms/op 1.16
compare ViewDUs 4.1051 s/op 3.2772 s/op 1.25
compare each validator Uint8Array 1.5573 s/op 1.6820 s/op 0.93
compare ViewDU to Uint8Array 1.2889 s/op 1.1080 s/op 1.16
migrate state 1000000 validators, 24 modified, 0 new 642.52 ms/op 607.18 ms/op 1.06
migrate state 1000000 validators, 1700 modified, 1000 new 916.66 ms/op 1.0088 s/op 0.91
migrate state 1000000 validators, 3400 modified, 2000 new 1.1687 s/op 1.3385 s/op 0.87
migrate state 1500000 validators, 24 modified, 0 new 675.94 ms/op 627.73 ms/op 1.08
migrate state 1500000 validators, 1700 modified, 1000 new 877.72 ms/op 926.79 ms/op 0.95
migrate state 1500000 validators, 3400 modified, 2000 new 1.1449 s/op 1.3565 s/op 0.84
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.0300 ns/op 5.6100 ns/op 0.72
state getBlockRootAtSlot - 250000 vs - 7PWei 658.45 ns/op 734.05 ns/op 0.90
computeProposers - vc 250000 8.6700 ms/op 6.2852 ms/op 1.38
computeEpochShuffling - vc 250000 97.930 ms/op 86.054 ms/op 1.14
getNextSyncCommittee - vc 250000 139.76 ms/op 99.350 ms/op 1.41
computeSigningRoot for AttestationData 26.015 us/op 26.717 us/op 0.97
hash AttestationData serialized data then Buffer.toString(base64) 1.6037 us/op 1.2649 us/op 1.27
toHexString serialized data 957.76 ns/op 823.34 ns/op 1.16
Buffer.toString(base64) 215.65 ns/op 167.13 ns/op 1.29

Please sign in to comment.