Repository: ChainSafe/lodestar
Pull request #7566: feat: lazy load pending deposits
Author: login: twoeths
Created: 2025-03-13T10:06:01Z | Merged: 2025-03-13T18:22:09Z

**Motivation**

- loading all pending deposit list is not efficient and it causes performance issue for lodestar, see https://github.com/ChainSafe/lodestar/issues/7565#issuecomment-2720303039

**Description**

- consume this in-progress ssz PR https://github.com/ChainSafe/ssz/pull/472/files
- lazy load pending deposits, 100 items per batch

potentially Closes #7565

**Test**
- verifying on feat1 (64)

Linked issue #7565: processPendingDeposits performance issue
### Describe the bug

this is on holesky

<img width="982" alt="Image" src="https://github.com/user-attachments/assets/ee9bda85-2960-41e7-a546-5d3b70ac6290" />

### Expected behavior

should reduce significantly. I guess we load all pending deposits while we don't need to loop all of them, will confirm through a profile

### Steps to reproduce

_No response_

### Additional context

_No response_

### Operating system

Linux

### Lodestar version or commit hash

v1.27.1
Linked issue comments: user: login: twoeths
created_at: 2025-03-13T08:04:18Z
body: [process_pending_deposits_Mar_13_2025.cpuprofile.zip](https://github.com/user-attachments/files/19224778/process_pending_deposits_Mar_13_2025.cpuprofile.zip)

it was mainly due to `getAllReadOnly()`

<img width="1508" alt="Image" src="https://github.com/user-attachments/assets/ecfc781f-546e-4a5d-980a-ca685df2830a" />
author_association: CONTRIBUTOR
user: login: twoeths
created_at: 2025-03-13T08:54:49Z
body: ssz needs to support an api to get items by chunk, that's implemented in https://github.com/ChainSafe/ssz/pull/472
author_association: CONTRIBUTOR

Diff:
diff --git a/packages/state-transition/src/epoch/processPendingDeposits.ts b/packages/state-transition/src/epoch/processPendingDeposits.ts
index 441d5601a380..f8bb24f81e5a 100644
--- a/packages/state-transition/src/epoch/processPendingDeposits.ts
+++ b/packages/state-transition/src/epoch/processPendingDeposits.ts
@@ -25,57 +25,67 @@ export function processPendingDeposits(state: CachedBeaconStateElectra, cache: E
   let isChurnLimitReached = false;
   const finalizedSlot = computeStartSlotAtEpoch(state.finalizedCheckpoint.epoch);
 
-  for (const deposit of state.pendingDeposits.getAllReadonly()) {
-    // Do not process deposit requests if Eth1 bridge deposits are not yet applied.
-    if (
-      // Is deposit request
-      deposit.slot > GENESIS_SLOT &&
-      // There are pending Eth1 bridge deposits
-      state.eth1DepositIndex < state.depositRequestsStartIndex
-    ) {
-      break;
-    }
+  let startIndex = 0;
+  // TODO: is this a good number?
+  const chunk = 100;
+  const pendingDepositsLength = state.pendingDeposits.length;
+  outer: while (startIndex < pendingDepositsLength) {
+    const deposits = state.pendingDeposits.getReadonlyByRange(startIndex, chunk);
 
-    // Check if deposit has been finalized, otherwise, stop processing.
-    if (deposit.slot > finalizedSlot) {
-      break;
-    }
+    for (const deposit of deposits) {
+      // Do not process deposit requests if Eth1 bridge deposits are not yet applied.
+      if (
+        // Is deposit request
+        deposit.slot > GENESIS_SLOT &&
+        // There are pending Eth1 bridge deposits
+        state.eth1DepositIndex < state.depositRequestsStartIndex
+      ) {
+        break outer;
+      }
 
-    // Check if number of processed deposits has not reached the limit, otherwise, stop processing.
-    if (nextDepositIndex >= MAX_PENDING_DEPOSITS_PER_EPOCH) {
-      break;
-    }
+      // Check if deposit has been finalized, otherwise, stop processing.
+      if (deposit.slot > finalizedSlot) {
+        break outer;
+      }
 
-    // Read validator state
-    let isValidatorExited = false;
-    let isValidatorWithdrawn = false;
+      // Check if number of processed deposits has not reached the limit, otherwise, stop processing.
+      if (nextDepositIndex >= MAX_PENDING_DEPOSITS_PER_EPOCH) {
+        break outer;
+      }
 
-    const validatorIndex = state.epochCtx.getValidatorIndex(deposit.pubkey);
-    if (isValidatorKnown(state, validatorIndex)) {
-      const validator = state.validators.getReadonly(validatorIndex);
-      isValidatorExited = validator.exitEpoch < FAR_FUTURE_EPOCH;
-      isValidatorWithdrawn = validator.withdrawableEpoch < nextEpoch;
-    }
+      // Read validator state
+      let isValidatorExited = false;
+      let isValidatorWithdrawn = false;
 
-    if (isValidatorWithdrawn) {
-      // Deposited balance will never become active. Increase balance but do not consume churn
-      applyPendingDeposit(state, deposit, cache);
-    } else if (isValidatorExited) {
-      // Validator is exiting, postpone the deposit until after withdrawable epoch
-      depositsToPostpone.push(deposit);
-    } else {
-      // Check if deposit fits in the churn, otherwise, do no more deposit processing in this epoch.
-      isChurnLimitReached = processedAmount + deposit.amount > availableForProcessing;
-      if (isChurnLimitReached) {
-        break;
+      const validatorIndex = state.epochCtx.getValidatorIndex(deposit.pubkey);
+      if (isValidatorKnown(state, validatorIndex)) {
+        const validator = state.validators.getReadonly(validatorIndex);
+        isValidatorExited = validator.exitEpoch < FAR_FUTURE_EPOCH;
+        isValidatorWithdrawn = validator.withdrawableEpoch < nextEpoch;
       }
-      // Consume churn and apply deposit.
-      processedAmount += deposit.amount;
-      applyPendingDeposit(state, deposit, cache);
+
+      if (isValidatorWithdrawn) {
+        // Deposited balance will never become active. Increase balance but do not consume churn
+        applyPendingDeposit(state, deposit, cache);
+      } else if (isValidatorExited) {
+        // Validator is exiting, postpone the deposit until after withdrawable epoch
+        depositsToPostpone.push(deposit);
+      } else {
+        // Check if deposit fits in the churn, otherwise, do no more deposit processing in this epoch.
+        isChurnLimitReached = processedAmount + deposit.amount > availableForProcessing;
+        if (isChurnLimitReached) {
+          break outer;
+        }
+        // Consume churn and apply deposit.
+        processedAmount += deposit.amount;
+        applyPendingDeposit(state, deposit, cache);
+      }
+
+      // Regardless of how the deposit was handled, we move on in the queue.
+      nextDepositIndex++;
     }
 
-    // Regardless of how the deposit was handled, we move on in the queue.
-    nextDepositIndex++;
+    startIndex += chunk;
   }
 
   const remainingPendingDeposits = state.pendingDeposits.sliceFrom(nextDepositIndex);
diff --git a/yarn.lock b/yarn.lock
index 8c5a8ae2edc5..3bbc67246ce1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -439,16 +439,16 @@
   resolved "https://registry.yarnpkg.com/@chainsafe/as-chacha20poly1305/-/as-chacha20poly1305-0.1.0.tgz#7da6f8796f9b42dac6e830a086d964f1f9189e09"
   integrity sha512-BpNcL8/lji/GM3+vZ/bgRWqJ1q5kwvTFmGPk7pxm/QQZDbaMI98waOHjEymTjq2JmdD/INdNBFOVSyJofXg7ew==
 
-"@chainsafe/as-sha256@1.0.0", "@chainsafe/as-sha256@^1.0.0":
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-1.0.0.tgz#9095ad42dce13887b5877fce70592e573940ecd7"
-  integrity sha512-EYw5IZ99Mhn7K8d1eDDH66AFhPy9GcD7bfiqm9mwFjsg8MViEEicGl62b5YPzufBTFh7X7qWAe6yWpr/gbaVEw==
-
 "@chainsafe/as-sha256@^0.4.1":
   version "0.4.1"
   resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.4.1.tgz#cfc0737e25f8c206767bdb6703e7943e5d44513e"
   integrity sha512-IqeeGwQihK6Y2EYLFofqs2eY2ep1I2MvQXHzOAI+5iQN51OZlUkrLgyAugu2x86xZewDk5xas7lNczkzFzF62w==
 
+"@chainsafe/as-sha256@^1.0.0", "@chainsafe/as-sha256@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-1.0.1.tgz#9fa9ab73c9748c1160ec5125059bd9f4f9185f68"
+  integrity sha512-4Y/kQm0LsJ6QRtGcMq6gOdQP+fZhWDfIV2eIqP6oFJZBWYGmdh3wm8YbrXDPLJO87X2Fu6koRLdUS00O3k14Hw==
+
 "@chainsafe/benchmark@^1.2.3":
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/@chainsafe/benchmark/-/benchmark-1.2.3.tgz#568d62e898077eec3bf4a035cbee49f8c8d7cf4e"
@@ -696,15 +696,6 @@
   dependencies:
     "@chainsafe/is-ip" "^2.0.1"
 
-"@chainsafe/persistent-merkle-tree@1.0.1", "@chainsafe/persistent-merkle-tree@^1.0.1":
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-1.0.1.tgz#4eb5a8e3367bc3957c88c8b9bad9610209e00fed"
-  integrity sha512-aQtYdXHmWRowcQK0h91HfHMO3bezQLk9wjQXv2CCcTbTim31BnCbPVpNbvAUWvEbifLQYvM18moygvEtdUNhXg==
-  dependencies:
-    "@chainsafe/as-sha256" "1.0.0"
-    "@chainsafe/hashtree" "1.0.1"
-    "@noble/hashes" "^1.3.0"
-
 "@chainsafe/persistent-merkle-tree@^0.6.1":
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.6.1.tgz#37bde25cf6cbe1660ad84311aa73157dc86ec7f2"
@@ -713,6 +704,15 @@
     "@chainsafe/as-sha256" "^0.4.1"
     "@noble/hashes" "^1.3.0"
 
+"@chainsafe/persistent-merkle-tree@^1.0.1", "@chainsafe/persistent-merkle-tree@^1.0.2":
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-1.0.2.tgz#e6154d3f6a2046c06f0ff64ac5634b72057959f3"
+  integrity sha512-9yPy1T8VIsN5pogFjMOW7bUATyoQShoKRu/7YUpHb8bkAeMk+5jUHA9FY3rWdGTApnAQnCQNbVcg+VCJfZt8cg==
+  dependencies:
+    "@chainsafe/as-sha256" "^1.0.1"
+    "@chainsafe/hashtree" "1.0.1"
+    "@noble/hashes" "^1.3.0"
+
 "@chainsafe/persistent-ts@^1.0.0":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@chainsafe/persistent-ts/-/persistent-ts-1.0.0.tgz#09ed7ab163a72d8ee9a154be589901bbc570a359"
@@ -768,12 +768,12 @@
     "@chainsafe/persistent-merkle-tree" "^0.6.1"
 
 "@chainsafe/ssz@^1.0.2":
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-1.0.2.tgz#af09775ac1f14c19a75bfd45279f71dce67545a1"
-  integrity sha512-T/hiLYRJoM0NkTgTc6XLIL5Nobc/poNqFnJ/8GlvG08czCcri5l8H5DF/6RKdL+1a++LRZCdtHElMaFryszkww==
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-1.0.3.tgz#c15fede5c1c75bc153b9b0c95e9d4953ecc31a1b"
+  integrity sha512-vmvR2FNpCHKK88E1vi1x2EzMMuYd6HTS9/lS63yX9yU4r4xe3keZ8SHcFmX0tZN+rGGPO52jXLNVWQpJI5uLmw==
   dependencies:
-    "@chainsafe/as-sha256" "1.0.0"
-    "@chainsafe/persistent-merkle-tree" "1.0.1"
+    "@chainsafe/as-sha256" "^1.0.1"
+    "@chainsafe/persistent-merkle-tree" "^1.0.2"
 
 "@chainsafe/swap-or-not-shuffle-darwin-arm64@0.0.2":
   version "0.0.2"


Reviews:
user: login: twoeths
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T13:11:53Z
user: login: wemeetagain
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T18:21:53Z
user: login: wemeetagain
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-13T18:21:56Z

Review comments:
diff_hunk: @@ -25,57 +25,67 @@ export function processPendingDeposits(state: CachedBeaconStateElectra, cache: E
   let isChurnLimitReached = false;
   const finalizedSlot = computeStartSlotAtEpoch(state.finalizedCheckpoint.epoch);
 
path: packages/state-transition/src/epoch/processPendingDeposits.ts
user: login: twoeths
body: this file is the main fix, other `*.ts` will be excluded in the final version
created_at: 2025-03-13T13:11:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -25,57 +25,67 @@ export function processPendingDeposits(state: CachedBeaconStateElectra, cache: E
   let isChurnLimitReached = false;
   const finalizedSlot = computeStartSlotAtEpoch(state.finalizedCheckpoint.epoch);
 
-  for (const deposit of state.pendingDeposits.getAllReadonly()) {
-    // Do not process deposit requests if Eth1 bridge deposits are not yet applied.
-    if (
-      // Is deposit request
-      deposit.slot > GENESIS_SLOT &&
-      // There are pending Eth1 bridge deposits
-      state.eth1DepositIndex < state.depositRequestsStartIndex
-    ) {
-      break;
-    }
+  let startIndex = 0;
+  // TODO: is this a good number?
path: packages/state-transition/src/epoch/processPendingDeposits.ts
user: login: wemeetagain
body: 100 seems good enough for now, we can revisit later w/ more data
created_at: 2025-03-13T18:21:53Z
author_association: MEMBER

PR comments:
user: login: twoeths
created_at: 2025-03-13T12:36:35Z
body: it's confirmed to fix the issue on feat1, was reduced from up to 3s to up to 350ms

<img width="1060" alt="Screenshot 2025-03-13 at 19 35 09" src="https://github.com/user-attachments/assets/aa922ac7-9d2f-4f62-8f6b-b6b2a09334d1" />

waiting for https://github.com/ChainSafe/ssz/pull/472/files then release ssz v1.0.3 then apply to this PR (and rebase against `unstable`)
author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-03-13T17:19:28Z
body: ## [Codecov](https://app.codecov.io/gh/ChainSafe/lodestar/pull/7566?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ChainSafe) Report
Attention: Patch coverage is `0%` with `39 lines` in your changes missing coverage. Please review.
> Project coverage is 50.12%. Comparing base [(`9f78c9d`)](https://app.codecov.io/gh/ChainSafe/lodestar/commit/9f78c9dad8200fc72e3f1ecca78647d4019673c0?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ChainSafe) to head [(`a10de1a`)](https://app.codecov.io/gh/ChainSafe/lodestar/commit/a10de1a4eeec9e7dc11259856e252a28669daf64?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ChainSafe).
> Report is 2 commits behind head on unstable.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##           unstable    #7566   +/-   ##
=========================================
  Coverage     50.11%   50.12%           
=========================================
  Files           603      603           
  Lines         40471    40478    +7     
  Branches       2225     2231    +6     
=========================================
+ Hits          20284    20291    +7     
  Misses        20147    20147           
  Partials         40       40           
```

</details>
<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- 📦 [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-13T18:00:12Z
body: 
## :warning: **Performance Alert** :warning:

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



<table>
<thead>
<tr>
    <th>Benchmark suite</th>
    <th>Current: 118a53bb5c4f9165fdd4977d73c8921995a02b58</th>
    <th>Previous: 9f78c9dad8200fc72e3f1ecca78647d4019673c0</th>
    <th>Ratio</th>
</tr>
</thead>
<tbody>
  <tr>
    <td>getSlashingsAndExits - default max</td>
    <td>235.43 us/op</td>
    <td>69.401 us/op</td>
    <td>3.39</td>
  </tr>
  <tr>
    <td>altair processBlock - 250000 vs - 7PWei normalcase</td>
    <td>12.135 ms/op</td>
    <td>3.5485 ms/op</td>
    <td>3.42</td>
  </tr>
</tbody>
</table>



<details><summary>Full benchmark results</summary>


<table>
<thead>
<tr>
    <th>Benchmark suite</th>
    <th>Current: 118a53bb5c4f9165fdd4977d73c8921995a02b58</th>
    <th>Previous: 9f78c9dad8200fc72e3f1ecca78647d4019673c0</th>
    <th>Ratio</th>
</tr>
</thead>
<tbody>
  <tr>
    <td>getPubkeys - index2pubkey - req 1000 vs - 250000 vc</td>
    <td>1.0999 ms/op</td>
    <td>761.36 us/op</td>
    <td>1.44</td>
  </tr>
  <tr>
    <td>getPubkeys - validatorsArr - req 1000 vs - 250000 vc</td>
    <td>39.376 us/op</td>
    <td>29.119 us/op</td>
    <td>1.35</td>
  </tr>
  <tr>
    <td>BLS verify - blst</td>
    <td>939.59 us/op</td>
    <td>805.97 us/op</td>
    <td>1.17</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures 3 - blst</td>
    <td>1.4828 ms/op</td>
    <td>1.3282 ms/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures 8 - blst</td>
    <td>1.9840 ms/op</td>
    <td>2.0169 ms/op</td>
    <td>0.98</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures 32 - blst</td>
    <td>5.9891 ms/op</td>
    <td>4.5676 ms/op</td>
    <td>1.31</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures 64 - blst</td>
    <td>11.297 ms/op</td>
    <td>8.7551 ms/op</td>
    <td>1.29</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures 128 - blst</td>
    <td>18.254 ms/op</td>
    <td>16.355 ms/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>BLS deserializing 10000 signatures</td>
    <td>726.27 ms/op</td>
    <td>624.25 ms/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>BLS deserializing 100000 signatures</td>
    <td>7.2626  s/op</td>
    <td>6.2785  s/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures - same message - 3 - blst</td>
    <td>940.50 us/op</td>
    <td>856.30 us/op</td>
    <td>1.10</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures - same message - 8 - blst</td>
    <td>1.1688 ms/op</td>
    <td>1.1151 ms/op</td>
    <td>1.05</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures - same message - 32 - blst</td>
    <td>1.7504 ms/op</td>
    <td>1.6864 ms/op</td>
    <td>1.04</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures - same message - 64 - blst</td>
    <td>2.6399 ms/op</td>
    <td>2.5641 ms/op</td>
    <td>1.03</td>
  </tr>
  <tr>
    <td>BLS verifyMultipleSignatures - same message - 128 - blst</td>
    <td>4.5831 ms/op</td>
    <td>4.1855 ms/op</td>
    <td>1.09</td>
  </tr>
  <tr>
    <td>BLS aggregatePubkeys 32 - blst</td>
    <td>19.930 us/op</td>
    <td>18.032 us/op</td>
    <td>1.11</td>
  </tr>
  <tr>
    <td>BLS aggregatePubkeys 128 - blst</td>
    <td>70.832 us/op</td>
    <td>63.465 us/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>notSeenSlots=1 numMissedVotes=1 numBadVotes=10</td>
    <td>56.939 ms/op</td>
    <td>57.276 ms/op</td>
    <td>0.99</td>
  </tr>
  <tr>
    <td>notSeenSlots=1 numMissedVotes=0 numBadVotes=4</td>
    <td>56.416 ms/op</td>
    <td>53.910 ms/op</td>
    <td>1.05</td>
  </tr>
  <tr>
    <td>notSeenSlots=2 numMissedVotes=1 numBadVotes=10</td>
    <td>44.964 ms/op</td>
    <td>39.623 ms/op</td>
    <td>1.13</td>
  </tr>
  <tr>
    <td>getSlashingsAndExits - default max</td>
    <td>235.43 us/op</td>
    <td>69.401 us/op</td>
    <td>3.39</td>
  </tr>
  <tr>
    <td>getSlashingsAndExits - 2k</td>
    <td>473.39 us/op</td>
    <td>372.50 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>proposeBlockBody type=full, size=empty</td>
    <td>7.2125 ms/op</td>
    <td>5.3829 ms/op</td>
    <td>1.34</td>
  </tr>
  <tr>
    <td>isKnown best case - 1 super set check</td>
    <td>216.00 ns/op</td>
    <td>434.00 ns/op</td>
    <td>0.50</td>
  </tr>
  <tr>
    <td>isKnown normal case - 2 super set checks</td>
    <td>211.00 ns/op</td>
    <td>430.00 ns/op</td>
    <td>0.49</td>
  </tr>
  <tr>
    <td>isKnown worse case - 16 super set checks</td>
    <td>211.00 ns/op</td>
    <td>428.00 ns/op</td>
    <td>0.49</td>
  </tr>
  <tr>
    <td>InMemoryCheckpointStateCache - add get delete</td>
    <td>3.1180 us/op</td>
    <td>2.5780 us/op</td>
    <td>1.21</td>
  </tr>
  <tr>
    <td>validate api signedAggregateAndProof - struct</td>
    <td>1.8853 ms/op</td>
    <td>1.6202 ms/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>validate gossip signedAggregateAndProof - struct</td>
    <td>1.6561 ms/op</td>
    <td>1.5229 ms/op</td>
    <td>1.09</td>
  </tr>
  <tr>
    <td>batch validate gossip attestation - vc 640000 - chunk 32</td>
    <td>148.27 us/op</td>
    <td>121.09 us/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>batch validate gossip attestation - vc 640000 - chunk 64</td>
    <td>138.08 us/op</td>
    <td>101.44 us/op</td>
    <td>1.36</td>
  </tr>
  <tr>
    <td>batch validate gossip attestation - vc 640000 - chunk 128</td>
    <td>137.06 us/op</td>
    <td>93.535 us/op</td>
    <td>1.47</td>
  </tr>
  <tr>
    <td>batch validate gossip attestation - vc 640000 - chunk 256</td>
    <td>133.65 us/op</td>
    <td>98.062 us/op</td>
    <td>1.36</td>
  </tr>
  <tr>
    <td>pickEth1Vote - no votes</td>
    <td>1.0220 ms/op</td>
    <td>787.30 us/op</td>
    <td>1.30</td>
  </tr>
  <tr>
    <td>pickEth1Vote - max votes</td>
    <td>10.120 ms/op</td>
    <td>4.5729 ms/op</td>
    <td>2.21</td>
  </tr>
  <tr>
    <td>pickEth1Vote - Eth1Data hashTreeRoot value x2048</td>
    <td>23.757 ms/op</td>
    <td>11.520 ms/op</td>
    <td>2.06</td>
  </tr>
  <tr>
    <td>pickEth1Vote - Eth1Data hashTreeRoot tree x2048</td>
    <td>26.598 ms/op</td>
    <td>16.252 ms/op</td>
    <td>1.64</td>
  </tr>
  <tr>
    <td>pickEth1Vote - Eth1Data fastSerialize value x2048</td>
    <td>452.51 us/op</td>
    <td>357.61 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>pickEth1Vote - Eth1Data fastSerialize tree x2048</td>
    <td>3.0774 ms/op</td>
    <td>2.0806 ms/op</td>
    <td>1.48</td>
  </tr>
  <tr>
    <td>bytes32 toHexString</td>
    <td>429.00 ns/op</td>
    <td>544.00 ns/op</td>
    <td>0.79</td>
  </tr>
  <tr>
    <td>bytes32 Buffer.toString(hex)</td>
    <td>268.00 ns/op</td>
    <td>449.00 ns/op</td>
    <td>0.60</td>
  </tr>
  <tr>
    <td>bytes32 Buffer.toString(hex) from Uint8Array</td>
    <td>343.00 ns/op</td>
    <td>523.00 ns/op</td>
    <td>0.66</td>
  </tr>
  <tr>
    <td>bytes32 Buffer.toString(hex) + 0x</td>
    <td>262.00 ns/op</td>
    <td>451.00 ns/op</td>
    <td>0.58</td>
  </tr>
  <tr>
    <td>Object access 1 prop</td>
    <td>0.12000 ns/op</td>
    <td>0.32100 ns/op</td>
    <td>0.37</td>
  </tr>
  <tr>
    <td>Map access 1 prop</td>
    <td>0.12500 ns/op</td>
    <td>0.32800 ns/op</td>
    <td>0.38</td>
  </tr>
  <tr>
    <td>Object get x1000</td>
    <td>6.0810 ns/op</td>
    <td>5.3330 ns/op</td>
    <td>1.14</td>
  </tr>
  <tr>
    <td>Map get x1000</td>
    <td>6.5470 ns/op</td>
    <td>5.9410 ns/op</td>
    <td>1.10</td>
  </tr>
  <tr>
    <td>Object set x1000</td>
    <td>33.215 ns/op</td>
    <td>19.960 ns/op</td>
    <td>1.66</td>
  </tr>
  <tr>
    <td>Map set x1000</td>
    <td>23.653 ns/op</td>
    <td>17.581 ns/op</td>
    <td>1.35</td>
  </tr>
  <tr>
    <td>Return object 10000 times</td>
    <td>0.30060 ns/op</td>
    <td>0.30680 ns/op</td>
    <td>0.98</td>
  </tr>
  <tr>
    <td>Throw Error 10000 times</td>
    <td>4.5697 us/op</td>
    <td>3.7068 us/op</td>
    <td>1.23</td>
  </tr>
  <tr>
    <td>toHex</td>
    <td>140.54 ns/op</td>
    <td>102.42 ns/op</td>
    <td>1.37</td>
  </tr>
  <tr>
    <td>Buffer.from</td>
    <td>133.36 ns/op</td>
    <td>93.222 ns/op</td>
    <td>1.43</td>
  </tr>
  <tr>
    <td>shared Buffer</td>
    <td>111.09 ns/op</td>
    <td>62.938 ns/op</td>
    <td>1.77</td>
  </tr>
  <tr>
    <td>fastMsgIdFn sha256 / 200 bytes</td>
    <td>2.4500 us/op</td>
    <td>2.0040 us/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>fastMsgIdFn h32 xxhash / 200 bytes</td>
    <td>297.00 ns/op</td>
    <td>416.00 ns/op</td>
    <td>0.71</td>
  </tr>
  <tr>
    <td>fastMsgIdFn h64 xxhash / 200 bytes</td>
    <td>302.00 ns/op</td>
    <td>480.00 ns/op</td>
    <td>0.63</td>
  </tr>
  <tr>
    <td>fastMsgIdFn sha256 / 1000 bytes</td>
    <td>7.6140 us/op</td>
    <td>5.9130 us/op</td>
    <td>1.29</td>
  </tr>
  <tr>
    <td>fastMsgIdFn h32 xxhash / 1000 bytes</td>
    <td>356.00 ns/op</td>
    <td>533.00 ns/op</td>
    <td>0.67</td>
  </tr>
  <tr>
    <td>fastMsgIdFn h64 xxhash / 1000 bytes</td>
    <td>359.00 ns/op</td>
    <td>550.00 ns/op</td>
    <td>0.65</td>
  </tr>
  <tr>
    <td>fastMsgIdFn sha256 / 10000 bytes</td>
    <td>69.510 us/op</td>
    <td>50.546 us/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>fastMsgIdFn h32 xxhash / 10000 bytes</td>
    <td>1.9180 us/op</td>
    <td>1.9870 us/op</td>
    <td>0.97</td>
  </tr>
  <tr>
    <td>fastMsgIdFn h64 xxhash / 10000 bytes</td>
    <td>1.2570 us/op</td>
    <td>1.4130 us/op</td>
    <td>0.89</td>
  </tr>
  <tr>
    <td>send data - 1000 256B messages</td>
    <td>17.482 ms/op</td>
    <td>12.856 ms/op</td>
    <td>1.36</td>
  </tr>
  <tr>
    <td>send data - 1000 512B messages</td>
    <td>20.212 ms/op</td>
    <td>16.251 ms/op</td>
    <td>1.24</td>
  </tr>
  <tr>
    <td>send data - 1000 1024B messages</td>
    <td>31.700 ms/op</td>
    <td>26.782 ms/op</td>
    <td>1.18</td>
  </tr>
  <tr>
    <td>send data - 1000 1200B messages</td>
    <td>28.129 ms/op</td>
    <td>21.747 ms/op</td>
    <td>1.29</td>
  </tr>
  <tr>
    <td>send data - 1000 2048B messages</td>
    <td>32.156 ms/op</td>
    <td>22.112 ms/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>send data - 1000 4096B messages</td>
    <td>30.431 ms/op</td>
    <td>23.899 ms/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>send data - 1000 16384B messages</td>
    <td>88.290 ms/op</td>
    <td>69.878 ms/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>send data - 1000 65536B messages</td>
    <td>241.18 ms/op</td>
    <td>242.78 ms/op</td>
    <td>0.99</td>
  </tr>
  <tr>
    <td>enrSubnets - fastDeserialize 64 bits</td>
    <td>1.5350 us/op</td>
    <td>1.0290 us/op</td>
    <td>1.49</td>
  </tr>
  <tr>
    <td>enrSubnets - ssz BitVector 64 bits</td>
    <td>335.00 ns/op</td>
    <td>509.00 ns/op</td>
    <td>0.66</td>
  </tr>
  <tr>
    <td>enrSubnets - fastDeserialize 4 bits</td>
    <td>161.00 ns/op</td>
    <td>329.00 ns/op</td>
    <td>0.49</td>
  </tr>
  <tr>
    <td>enrSubnets - ssz BitVector 4 bits</td>
    <td>378.00 ns/op</td>
    <td>514.00 ns/op</td>
    <td>0.74</td>
  </tr>
  <tr>
    <td>prioritizePeers score -10:0 att 32-0.1 sync 2-0</td>
    <td>129.61 us/op</td>
    <td>101.66 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>prioritizePeers score 0:0 att 32-0.25 sync 2-0.25</td>
    <td>189.61 us/op</td>
    <td>126.80 us/op</td>
    <td>1.50</td>
  </tr>
  <tr>
    <td>prioritizePeers score 0:0 att 32-0.5 sync 2-0.5</td>
    <td>222.62 us/op</td>
    <td>175.44 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>prioritizePeers score 0:0 att 64-0.75 sync 4-0.75</td>
    <td>415.57 us/op</td>
    <td>330.33 us/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>prioritizePeers score 0:0 att 64-1 sync 4-1</td>
    <td>503.54 us/op</td>
    <td>403.27 us/op</td>
    <td>1.25</td>
  </tr>
  <tr>
    <td>array of 16000 items push then shift</td>
    <td>1.7695 us/op</td>
    <td>1.1953 us/op</td>
    <td>1.48</td>
  </tr>
  <tr>
    <td>LinkedList of 16000 items push then shift</td>
    <td>10.525 ns/op</td>
    <td>6.9840 ns/op</td>
    <td>1.51</td>
  </tr>
  <tr>
    <td>array of 16000 items push then pop</td>
    <td>94.419 ns/op</td>
    <td>63.134 ns/op</td>
    <td>1.50</td>
  </tr>
  <tr>
    <td>LinkedList of 16000 items push then pop</td>
    <td>8.1480 ns/op</td>
    <td>6.0610 ns/op</td>
    <td>1.34</td>
  </tr>
  <tr>
    <td>array of 24000 items push then shift</td>
    <td>2.5525 us/op</td>
    <td>1.8043 us/op</td>
    <td>1.41</td>
  </tr>
  <tr>
    <td>LinkedList of 24000 items push then shift</td>
    <td>9.8030 ns/op</td>
    <td>6.7580 ns/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>array of 24000 items push then pop</td>
    <td>128.66 ns/op</td>
    <td>88.614 ns/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>LinkedList of 24000 items push then pop</td>
    <td>8.0580 ns/op</td>
    <td>6.0830 ns/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>intersect bitArray bitLen 8</td>
    <td>7.3270 ns/op</td>
    <td>5.2300 ns/op</td>
    <td>1.40</td>
  </tr>
  <tr>
    <td>intersect array and set length 8</td>
    <td>42.463 ns/op</td>
    <td>32.562 ns/op</td>
    <td>1.30</td>
  </tr>
  <tr>
    <td>intersect bitArray bitLen 128</td>
    <td>31.352 ns/op</td>
    <td>25.759 ns/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>intersect array and set length 128</td>
    <td>667.63 ns/op</td>
    <td>522.76 ns/op</td>
    <td>1.28</td>
  </tr>
  <tr>
    <td>bitArray.getTrueBitIndexes() bitLen 128</td>
    <td>1.1310 us/op</td>
    <td>1.1550 us/op</td>
    <td>0.98</td>
  </tr>
  <tr>
    <td>bitArray.getTrueBitIndexes() bitLen 248</td>
    <td>2.3100 us/op</td>
    <td>1.8920 us/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>bitArray.getTrueBitIndexes() bitLen 512</td>
    <td>4.2690 us/op</td>
    <td>3.6950 us/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>Buffer.concat 32 items</td>
    <td>759.00 ns/op</td>
    <td>721.00 ns/op</td>
    <td>1.05</td>
  </tr>
  <tr>
    <td>Uint8Array.set 32 items</td>
    <td>1.9310 us/op</td>
    <td>1.1900 us/op</td>
    <td>1.62</td>
  </tr>
  <tr>
    <td>Buffer.copy</td>
    <td>2.3300 us/op</td>
    <td>1.9430 us/op</td>
    <td>1.20</td>
  </tr>
  <tr>
    <td>Uint8Array.set - with subarray</td>
    <td>2.3970 us/op</td>
    <td>1.6790 us/op</td>
    <td>1.43</td>
  </tr>
  <tr>
    <td>Uint8Array.set - without subarray</td>
    <td>1.4370 us/op</td>
    <td>1.1620 us/op</td>
    <td>1.24</td>
  </tr>
  <tr>
    <td>getUint32 - dataview</td>
    <td>204.00 ns/op</td>
    <td>384.00 ns/op</td>
    <td>0.53</td>
  </tr>
  <tr>
    <td>getUint32 - manual</td>
    <td>125.00 ns/op</td>
    <td>307.00 ns/op</td>
    <td>0.41</td>
  </tr>
  <tr>
    <td>Set add up to 64 items then delete first</td>
    <td>3.1602 us/op</td>
    <td>1.7868 us/op</td>
    <td>1.77</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 64 items then delete first</td>
    <td>4.4036 us/op</td>
    <td>2.7881 us/op</td>
    <td>1.58</td>
  </tr>
  <tr>
    <td>Set add up to 64 items then delete last</td>
    <td>2.4750 us/op</td>
    <td>1.9498 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 64 items then delete last</td>
    <td>5.2451 us/op</td>
    <td>3.0515 us/op</td>
    <td>1.72</td>
  </tr>
  <tr>
    <td>Set add up to 64 items then delete middle</td>
    <td>3.3123 us/op</td>
    <td>1.9106 us/op</td>
    <td>1.73</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 64 items then delete middle</td>
    <td>7.1149 us/op</td>
    <td>4.7765 us/op</td>
    <td>1.49</td>
  </tr>
  <tr>
    <td>Set add up to 128 items then delete first</td>
    <td>6.7941 us/op</td>
    <td>4.2329 us/op</td>
    <td>1.61</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 128 items then delete first</td>
    <td>10.729 us/op</td>
    <td>6.4844 us/op</td>
    <td>1.65</td>
  </tr>
  <tr>
    <td>Set add up to 128 items then delete last</td>
    <td>6.7933 us/op</td>
    <td>4.0216 us/op</td>
    <td>1.69</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 128 items then delete last</td>
    <td>11.542 us/op</td>
    <td>6.2738 us/op</td>
    <td>1.84</td>
  </tr>
  <tr>
    <td>Set add up to 128 items then delete middle</td>
    <td>6.8205 us/op</td>
    <td>3.9627 us/op</td>
    <td>1.72</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 128 items then delete middle</td>
    <td>16.989 us/op</td>
    <td>12.764 us/op</td>
    <td>1.33</td>
  </tr>
  <tr>
    <td>Set add up to 256 items then delete first</td>
    <td>12.839 us/op</td>
    <td>8.2342 us/op</td>
    <td>1.56</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 256 items then delete first</td>
    <td>19.749 us/op</td>
    <td>13.549 us/op</td>
    <td>1.46</td>
  </tr>
  <tr>
    <td>Set add up to 256 items then delete last</td>
    <td>13.288 us/op</td>
    <td>8.0926 us/op</td>
    <td>1.64</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 256 items then delete last</td>
    <td>21.432 us/op</td>
    <td>12.292 us/op</td>
    <td>1.74</td>
  </tr>
  <tr>
    <td>Set add up to 256 items then delete middle</td>
    <td>12.372 us/op</td>
    <td>7.9753 us/op</td>
    <td>1.55</td>
  </tr>
  <tr>
    <td>OrderedSet add up to 256 items then delete middle</td>
    <td>48.369 us/op</td>
    <td>37.790 us/op</td>
    <td>1.28</td>
  </tr>
  <tr>
    <td>transfer serialized Status (84 B)</td>
    <td>3.1900 us/op</td>
    <td>2.1390 us/op</td>
    <td>1.49</td>
  </tr>
  <tr>
    <td>copy serialized Status (84 B)</td>
    <td>1.9060 us/op</td>
    <td>1.3020 us/op</td>
    <td>1.46</td>
  </tr>
  <tr>
    <td>transfer serialized SignedVoluntaryExit (112 B)</td>
    <td>2.8160 us/op</td>
    <td>2.1770 us/op</td>
    <td>1.29</td>
  </tr>
  <tr>
    <td>copy serialized SignedVoluntaryExit (112 B)</td>
    <td>1.7430 us/op</td>
    <td>1.3170 us/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>transfer serialized ProposerSlashing (416 B)</td>
    <td>4.3280 us/op</td>
    <td>2.1550 us/op</td>
    <td>2.01</td>
  </tr>
  <tr>
    <td>copy serialized ProposerSlashing (416 B)</td>
    <td>2.4380 us/op</td>
    <td>1.4390 us/op</td>
    <td>1.69</td>
  </tr>
  <tr>
    <td>transfer serialized Attestation (485 B)</td>
    <td>3.4580 us/op</td>
    <td>2.1530 us/op</td>
    <td>1.61</td>
  </tr>
  <tr>
    <td>copy serialized Attestation (485 B)</td>
    <td>2.2760 us/op</td>
    <td>1.4050 us/op</td>
    <td>1.62</td>
  </tr>
  <tr>
    <td>transfer serialized AttesterSlashing (33232 B)</td>
    <td>3.4650 us/op</td>
    <td>2.3830 us/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>copy serialized AttesterSlashing (33232 B)</td>
    <td>6.8480 us/op</td>
    <td>3.3890 us/op</td>
    <td>2.02</td>
  </tr>
  <tr>
    <td>transfer serialized Small SignedBeaconBlock (128000 B)</td>
    <td>3.8330 us/op</td>
    <td>2.8150 us/op</td>
    <td>1.36</td>
  </tr>
  <tr>
    <td>copy serialized Small SignedBeaconBlock (128000 B)</td>
    <td>16.785 us/op</td>
    <td>8.1010 us/op</td>
    <td>2.07</td>
  </tr>
  <tr>
    <td>transfer serialized Avg SignedBeaconBlock (200000 B)</td>
    <td>4.9590 us/op</td>
    <td>2.9500 us/op</td>
    <td>1.68</td>
  </tr>
  <tr>
    <td>copy serialized Avg SignedBeaconBlock (200000 B)</td>
    <td>22.299 us/op</td>
    <td>11.326 us/op</td>
    <td>1.97</td>
  </tr>
  <tr>
    <td>transfer serialized BlobsSidecar (524380 B)</td>
    <td>5.3180 us/op</td>
    <td>4.0690 us/op</td>
    <td>1.31</td>
  </tr>
  <tr>
    <td>copy serialized BlobsSidecar (524380 B)</td>
    <td>73.289 us/op</td>
    <td>122.56 us/op</td>
    <td>0.60</td>
  </tr>
  <tr>
    <td>transfer serialized Big SignedBeaconBlock (1000000 B)</td>
    <td>5.6020 us/op</td>
    <td>4.4540 us/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>copy serialized Big SignedBeaconBlock (1000000 B)</td>
    <td>137.56 us/op</td>
    <td>115.44 us/op</td>
    <td>1.19</td>
  </tr>
  <tr>
    <td>pass gossip attestations to forkchoice per slot</td>
    <td>3.1252 ms/op</td>
    <td>2.5682 ms/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 100000 bc 64 eq 0</td>
    <td>477.88 us/op</td>
    <td>367.78 us/op</td>
    <td>1.30</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 64 eq 0</td>
    <td>3.0484 ms/op</td>
    <td>2.2209 ms/op</td>
    <td>1.37</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 1000000 bc 64 eq 0</td>
    <td>5.0482 ms/op</td>
    <td>3.8572 ms/op</td>
    <td>1.31</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 320 eq 0</td>
    <td>3.0617 ms/op</td>
    <td>2.2193 ms/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 1200 eq 0</td>
    <td>3.0258 ms/op</td>
    <td>2.2506 ms/op</td>
    <td>1.34</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 7200 eq 0</td>
    <td>3.3346 ms/op</td>
    <td>2.4655 ms/op</td>
    <td>1.35</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 64 eq 1000</td>
    <td>10.756 ms/op</td>
    <td>9.4396 ms/op</td>
    <td>1.14</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 64 eq 10000</td>
    <td>10.744 ms/op</td>
    <td>9.2678 ms/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>forkChoice updateHead vc 600000 bc 64 eq 300000</td>
    <td>14.441 ms/op</td>
    <td>10.969 ms/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>computeDeltas 500000 validators 300 proto nodes</td>
    <td>4.3616 ms/op</td>
    <td>3.1531 ms/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>computeDeltas 500000 validators 1200 proto nodes</td>
    <td>4.4052 ms/op</td>
    <td>3.2032 ms/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>computeDeltas 500000 validators 7200 proto nodes</td>
    <td>4.4074 ms/op</td>
    <td>3.0288 ms/op</td>
    <td>1.46</td>
  </tr>
  <tr>
    <td>computeDeltas 750000 validators 300 proto nodes</td>
    <td>6.4761 ms/op</td>
    <td>4.5989 ms/op</td>
    <td>1.41</td>
  </tr>
  <tr>
    <td>computeDeltas 750000 validators 1200 proto nodes</td>
    <td>6.0392 ms/op</td>
    <td>4.5846 ms/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>computeDeltas 750000 validators 7200 proto nodes</td>
    <td>5.9776 ms/op</td>
    <td>4.5987 ms/op</td>
    <td>1.30</td>
  </tr>
  <tr>
    <td>computeDeltas 1400000 validators 300 proto nodes</td>
    <td>12.082 ms/op</td>
    <td>8.6514 ms/op</td>
    <td>1.40</td>
  </tr>
  <tr>
    <td>computeDeltas 1400000 validators 1200 proto nodes</td>
    <td>11.517 ms/op</td>
    <td>8.7148 ms/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>computeDeltas 1400000 validators 7200 proto nodes</td>
    <td>15.220 ms/op</td>
    <td>8.7872 ms/op</td>
    <td>1.73</td>
  </tr>
  <tr>
    <td>computeDeltas 2100000 validators 300 proto nodes</td>
    <td>21.384 ms/op</td>
    <td>13.110 ms/op</td>
    <td>1.63</td>
  </tr>
  <tr>
    <td>computeDeltas 2100000 validators 1200 proto nodes</td>
    <td>20.199 ms/op</td>
    <td>13.259 ms/op</td>
    <td>1.52</td>
  </tr>
  <tr>
    <td>computeDeltas 2100000 validators 7200 proto nodes</td>
    <td>18.735 ms/op</td>
    <td>13.055 ms/op</td>
    <td>1.44</td>
  </tr>
  <tr>
    <td>altair processAttestation - 250000 vs - 7PWei normalcase</td>
    <td>2.4785 ms/op</td>
    <td>1.7062 ms/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>altair processAttestation - 250000 vs - 7PWei worstcase</td>
    <td>3.6691 ms/op</td>
    <td>2.4681 ms/op</td>
    <td>1.49</td>
  </tr>
  <tr>
    <td>altair processAttestation - setStatus - 1/6 committees join</td>
    <td>138.47 us/op</td>
    <td>99.403 us/op</td>
    <td>1.39</td>
  </tr>
  <tr>
    <td>altair processAttestation - setStatus - 1/3 committees join</td>
    <td>262.86 us/op</td>
    <td>190.30 us/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>altair processAttestation - setStatus - 1/2 committees join</td>
    <td>374.50 us/op</td>
    <td>283.43 us/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>altair processAttestation - setStatus - 2/3 committees join</td>
    <td>480.41 us/op</td>
    <td>361.25 us/op</td>
    <td>1.33</td>
  </tr>
  <tr>
    <td>altair processAttestation - setStatus - 4/5 committees join</td>
    <td>771.01 us/op</td>
    <td>500.98 us/op</td>
    <td>1.54</td>
  </tr>
  <tr>
    <td>altair processAttestation - setStatus - 100% committees join</td>
    <td>794.13 us/op</td>
    <td>589.55 us/op</td>
    <td>1.35</td>
  </tr>
  <tr>
    <td>altair processBlock - 250000 vs - 7PWei normalcase</td>
    <td>12.135 ms/op</td>
    <td>3.5485 ms/op</td>
    <td>3.42</td>
  </tr>
  <tr>
    <td>altair processBlock - 250000 vs - 7PWei normalcase hashState</td>
    <td>35.264 ms/op</td>
    <td>24.807 ms/op</td>
    <td>1.42</td>
  </tr>
  <tr>
    <td>altair processBlock - 250000 vs - 7PWei worstcase</td>
    <td>44.571 ms/op</td>
    <td>38.746 ms/op</td>
    <td>1.15</td>
  </tr>
  <tr>
    <td>altair processBlock - 250000 vs - 7PWei worstcase hashState</td>
    <td>107.99 ms/op</td>
    <td>66.245 ms/op</td>
    <td>1.63</td>
  </tr>
  <tr>
    <td>phase0 processBlock - 250000 vs - 7PWei normalcase</td>
    <td>2.5801 ms/op</td>
    <td>1.6215 ms/op</td>
    <td>1.59</td>
  </tr>
  <tr>
    <td>phase0 processBlock - 250000 vs - 7PWei worstcase</td>
    <td>27.584 ms/op</td>
    <td>23.333 ms/op</td>
    <td>1.18</td>
  </tr>
  <tr>
    <td>altair processEth1Data - 250000 vs - 7PWei normalcase</td>
    <td>359.67 us/op</td>
    <td>281.86 us/op</td>
    <td>1.28</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15</td>
    <td>5.7880 us/op</td>
    <td>2.8100 us/op</td>
    <td>2.06</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219</td>
    <td>36.978 us/op</td>
    <td>28.796 us/op</td>
    <td>1.28</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42</td>
    <td>9.4460 us/op</td>
    <td>7.6610 us/op</td>
    <td>1.23</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18</td>
    <td>6.2050 us/op</td>
    <td>4.8670 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020</td>
    <td>159.14 us/op</td>
    <td>121.63 us/op</td>
    <td>1.31</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777</td>
    <td>1.1195 ms/op</td>
    <td>793.30 us/op</td>
    <td>1.41</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384</td>
    <td>1.4668 ms/op</td>
    <td>1.1083 ms/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384</td>
    <td>1.5903 ms/op</td>
    <td>1.1090 ms/op</td>
    <td>1.43</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384</td>
    <td>3.4101 ms/op</td>
    <td>2.9569 ms/op</td>
    <td>1.15</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384</td>
    <td>1.9602 ms/op</td>
    <td>1.1181 ms/op</td>
    <td>1.75</td>
  </tr>
  <tr>
    <td>getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384</td>
    <td>3.6020 ms/op</td>
    <td>2.9351 ms/op</td>
    <td>1.23</td>
  </tr>
  <tr>
    <td>Tree 40 250000 create</td>
    <td>467.70 ms/op</td>
    <td>370.96 ms/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>Tree 40 250000 get(125000)</td>
    <td>146.93 ns/op</td>
    <td>115.54 ns/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>Tree 40 250000 set(125000)</td>
    <td>1.7622 us/op</td>
    <td>1.2424 us/op</td>
    <td>1.42</td>
  </tr>
  <tr>
    <td>Tree 40 250000 toArray()</td>
    <td>20.603 ms/op</td>
    <td>9.6209 ms/op</td>
    <td>2.14</td>
  </tr>
  <tr>
    <td>Tree 40 250000 iterate all - toArray() + loop</td>
    <td>19.616 ms/op</td>
    <td>9.9282 ms/op</td>
    <td>1.98</td>
  </tr>
  <tr>
    <td>Tree 40 250000 iterate all - get(i)</td>
    <td>55.767 ms/op</td>
    <td>40.994 ms/op</td>
    <td>1.36</td>
  </tr>
  <tr>
    <td>Array 250000 create</td>
    <td>3.4704 ms/op</td>
    <td>1.9617 ms/op</td>
    <td>1.77</td>
  </tr>
  <tr>
    <td>Array 250000 clone - spread</td>
    <td>1.4479 ms/op</td>
    <td>627.32 us/op</td>
    <td>2.31</td>
  </tr>
  <tr>
    <td>Array 250000 get(125000)</td>
    <td>0.41600 ns/op</td>
    <td>0.57700 ns/op</td>
    <td>0.72</td>
  </tr>
  <tr>
    <td>Array 250000 set(125000)</td>
    <td>0.43700 ns/op</td>
    <td>0.59300 ns/op</td>
    <td>0.74</td>
  </tr>
  <tr>
    <td>Array 250000 iterate all - loop</td>
    <td>112.11 us/op</td>
    <td>77.500 us/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>phase0 afterProcessEpoch - 250000 vs - 7PWei</td>
    <td>51.274 ms/op</td>
    <td>41.565 ms/op</td>
    <td>1.23</td>
  </tr>
  <tr>
    <td>Array.fill - length 1000000</td>
    <td>3.5712 ms/op</td>
    <td>2.6251 ms/op</td>
    <td>1.36</td>
  </tr>
  <tr>
    <td>Array push - length 1000000</td>
    <td>12.897 ms/op</td>
    <td>10.245 ms/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>Array.get</td>
    <td>0.27747 ns/op</td>
    <td>0.26107 ns/op</td>
    <td>1.06</td>
  </tr>
  <tr>
    <td>Uint8Array.get</td>
    <td>0.44506 ns/op</td>
    <td>0.34496 ns/op</td>
    <td>1.29</td>
  </tr>
  <tr>
    <td>phase0 beforeProcessEpoch - 250000 vs - 7PWei</td>
    <td>19.628 ms/op</td>
    <td>12.878 ms/op</td>
    <td>1.52</td>
  </tr>
  <tr>
    <td>altair processEpoch - mainnet_e81889</td>
    <td>300.67 ms/op</td>
    <td>231.74 ms/op</td>
    <td>1.30</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair beforeProcessEpoch</td>
    <td>21.057 ms/op</td>
    <td>17.623 ms/op</td>
    <td>1.19</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processJustificationAndFinalization</td>
    <td>5.8990 us/op</td>
    <td>4.4990 us/op</td>
    <td>1.31</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processInactivityUpdates</td>
    <td>4.2586 ms/op</td>
    <td>3.3780 ms/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processRewardsAndPenalties</td>
    <td>46.451 ms/op</td>
    <td>36.156 ms/op</td>
    <td>1.28</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processRegistryUpdates</td>
    <td>703.00 ns/op</td>
    <td>880.00 ns/op</td>
    <td>0.80</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processSlashings</td>
    <td>178.00 ns/op</td>
    <td>398.00 ns/op</td>
    <td>0.45</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processEth1DataReset</td>
    <td>169.00 ns/op</td>
    <td>398.00 ns/op</td>
    <td>0.42</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processEffectiveBalanceUpdates</td>
    <td>1.2691 ms/op</td>
    <td>1.0149 ms/op</td>
    <td>1.25</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processSlashingsReset</td>
    <td>1.0270 us/op</td>
    <td>1.0010 us/op</td>
    <td>1.03</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processRandaoMixesReset</td>
    <td>1.2530 us/op</td>
    <td>1.4550 us/op</td>
    <td>0.86</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processHistoricalRootsUpdate</td>
    <td>173.00 ns/op</td>
    <td>399.00 ns/op</td>
    <td>0.43</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processParticipationFlagUpdates</td>
    <td>576.00 ns/op</td>
    <td>711.00 ns/op</td>
    <td>0.81</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair processSyncCommitteeUpdates</td>
    <td>137.00 ns/op</td>
    <td>363.00 ns/op</td>
    <td>0.38</td>
  </tr>
  <tr>
    <td>mainnet_e81889 - altair afterProcessEpoch</td>
    <td>52.508 ms/op</td>
    <td>41.354 ms/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>capella processEpoch - mainnet_e217614</td>
    <td>1.0422  s/op</td>
    <td>883.87 ms/op</td>
    <td>1.18</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella beforeProcessEpoch</td>
    <td>70.567 ms/op</td>
    <td>60.790 ms/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processJustificationAndFinalization</td>
    <td>5.3680 us/op</td>
    <td>4.3340 us/op</td>
    <td>1.24</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processInactivityUpdates</td>
    <td>17.140 ms/op</td>
    <td>11.476 ms/op</td>
    <td>1.49</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processRewardsAndPenalties</td>
    <td>190.03 ms/op</td>
    <td>178.47 ms/op</td>
    <td>1.06</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processRegistryUpdates</td>
    <td>7.3370 us/op</td>
    <td>5.9970 us/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processSlashings</td>
    <td>185.00 ns/op</td>
    <td>408.00 ns/op</td>
    <td>0.45</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processEth1DataReset</td>
    <td>171.00 ns/op</td>
    <td>384.00 ns/op</td>
    <td>0.45</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processEffectiveBalanceUpdates</td>
    <td>13.623 ms/op</td>
    <td>15.550 ms/op</td>
    <td>0.88</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processSlashingsReset</td>
    <td>1.0110 us/op</td>
    <td>1.1670 us/op</td>
    <td>0.87</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processRandaoMixesReset</td>
    <td>1.6550 us/op</td>
    <td>1.2600 us/op</td>
    <td>1.31</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processHistoricalRootsUpdate</td>
    <td>189.00 ns/op</td>
    <td>417.00 ns/op</td>
    <td>0.45</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella processParticipationFlagUpdates</td>
    <td>552.00 ns/op</td>
    <td>744.00 ns/op</td>
    <td>0.74</td>
  </tr>
  <tr>
    <td>mainnet_e217614 - capella afterProcessEpoch</td>
    <td>124.26 ms/op</td>
    <td>102.49 ms/op</td>
    <td>1.21</td>
  </tr>
  <tr>
    <td>phase0 processEpoch - mainnet_e58758</td>
    <td>330.23 ms/op</td>
    <td>277.92 ms/op</td>
    <td>1.19</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 beforeProcessEpoch</td>
    <td>81.067 ms/op</td>
    <td>72.525 ms/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processJustificationAndFinalization</td>
    <td>7.7520 us/op</td>
    <td>5.7740 us/op</td>
    <td>1.34</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processRewardsAndPenalties</td>
    <td>40.997 ms/op</td>
    <td>39.492 ms/op</td>
    <td>1.04</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processRegistryUpdates</td>
    <td>4.3040 us/op</td>
    <td>2.8850 us/op</td>
    <td>1.49</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processSlashings</td>
    <td>171.00 ns/op</td>
    <td>406.00 ns/op</td>
    <td>0.42</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processEth1DataReset</td>
    <td>168.00 ns/op</td>
    <td>402.00 ns/op</td>
    <td>0.42</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processEffectiveBalanceUpdates</td>
    <td>1.0450 ms/op</td>
    <td>883.88 us/op</td>
    <td>1.18</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processSlashingsReset</td>
    <td>997.00 ns/op</td>
    <td>1.1430 us/op</td>
    <td>0.87</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processRandaoMixesReset</td>
    <td>1.4260 us/op</td>
    <td>1.2570 us/op</td>
    <td>1.13</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processHistoricalRootsUpdate</td>
    <td>174.00 ns/op</td>
    <td>399.00 ns/op</td>
    <td>0.44</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 processParticipationRecordUpdates</td>
    <td>939.00 ns/op</td>
    <td>1.2330 us/op</td>
    <td>0.76</td>
  </tr>
  <tr>
    <td>mainnet_e58758 - phase0 afterProcessEpoch</td>
    <td>42.753 ms/op</td>
    <td>35.052 ms/op</td>
    <td>1.22</td>
  </tr>
  <tr>
    <td>phase0 processEffectiveBalanceUpdates - 250000 normalcase</td>
    <td>1.7720 ms/op</td>
    <td>944.58 us/op</td>
    <td>1.88</td>
  </tr>
  <tr>
    <td>phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5</td>
    <td>2.2409 ms/op</td>
    <td>1.4752 ms/op</td>
    <td>1.52</td>
  </tr>
  <tr>
    <td>altair processInactivityUpdates - 250000 normalcase</td>
    <td>21.581 ms/op</td>
    <td>15.676 ms/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>altair processInactivityUpdates - 250000 worstcase</td>
    <td>20.339 ms/op</td>
    <td>17.826 ms/op</td>
    <td>1.14</td>
  </tr>
  <tr>
    <td>phase0 processRegistryUpdates - 250000 normalcase</td>
    <td>10.401 us/op</td>
    <td>5.0700 us/op</td>
    <td>2.05</td>
  </tr>
  <tr>
    <td>phase0 processRegistryUpdates - 250000 badcase_full_deposits</td>
    <td>356.79 us/op</td>
    <td>277.31 us/op</td>
    <td>1.29</td>
  </tr>
  <tr>
    <td>phase0 processRegistryUpdates - 250000 worstcase 0.5</td>
    <td>136.97 ms/op</td>
    <td>93.288 ms/op</td>
    <td>1.47</td>
  </tr>
  <tr>
    <td>altair processRewardsAndPenalties - 250000 normalcase</td>
    <td>59.712 ms/op</td>
    <td>36.527 ms/op</td>
    <td>1.63</td>
  </tr>
  <tr>
    <td>altair processRewardsAndPenalties - 250000 worstcase</td>
    <td>40.307 ms/op</td>
    <td>34.936 ms/op</td>
    <td>1.15</td>
  </tr>
  <tr>
    <td>phase0 getAttestationDeltas - 250000 normalcase</td>
    <td>8.4005 ms/op</td>
    <td>5.2996 ms/op</td>
    <td>1.59</td>
  </tr>
  <tr>
    <td>phase0 getAttestationDeltas - 250000 worstcase</td>
    <td>6.1566 ms/op</td>
    <td>5.6133 ms/op</td>
    <td>1.10</td>
  </tr>
  <tr>
    <td>phase0 processSlashings - 250000 worstcase</td>
    <td>131.90 us/op</td>
    <td>92.488 us/op</td>
    <td>1.43</td>
  </tr>
  <tr>
    <td>altair processSyncCommitteeUpdates - 250000</td>
    <td>122.46 ms/op</td>
    <td>133.30 ms/op</td>
    <td>0.92</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - No change</td>
    <td>232.00 ns/op</td>
    <td>688.00 ns/op</td>
    <td>0.34</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 1 full validator</td>
    <td>93.660 us/op</td>
    <td>83.836 us/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 32 full validator</td>
    <td>953.25 us/op</td>
    <td>1.3347 ms/op</td>
    <td>0.71</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 512 full validator</td>
    <td>10.980 ms/op</td>
    <td>13.547 ms/op</td>
    <td>0.81</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 1 validator.effectiveBalance</td>
    <td>110.65 us/op</td>
    <td>118.14 us/op</td>
    <td>0.94</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 32 validator.effectiveBalance</td>
    <td>1.4295 ms/op</td>
    <td>2.1632 ms/op</td>
    <td>0.66</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 512 validator.effectiveBalance</td>
    <td>24.879 ms/op</td>
    <td>43.085 ms/op</td>
    <td>0.58</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 1 balances</td>
    <td>86.685 us/op</td>
    <td>130.62 us/op</td>
    <td>0.66</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 32 balances</td>
    <td>725.64 us/op</td>
    <td>1.5492 ms/op</td>
    <td>0.47</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 512 balances</td>
    <td>7.6027 ms/op</td>
    <td>12.421 ms/op</td>
    <td>0.61</td>
  </tr>
  <tr>
    <td>BeaconState.hashTreeRoot - 250000 balances</td>
    <td>172.80 ms/op</td>
    <td>268.53 ms/op</td>
    <td>0.64</td>
  </tr>
  <tr>
    <td>aggregationBits - 2048 els - zipIndexesInBitList</td>
    <td>21.999 us/op</td>
    <td>23.724 us/op</td>
    <td>0.93</td>
  </tr>
  <tr>
    <td>byteArrayEquals 32</td>
    <td>54.115 ns/op</td>
    <td>48.531 ns/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>Buffer.compare 32</td>
    <td>17.349 ns/op</td>
    <td>16.261 ns/op</td>
    <td>1.07</td>
  </tr>
  <tr>
    <td>byteArrayEquals 1024</td>
    <td>1.6032 us/op</td>
    <td>1.3391 us/op</td>
    <td>1.20</td>
  </tr>
  <tr>
    <td>Buffer.compare 1024</td>
    <td>25.882 ns/op</td>
    <td>25.146 ns/op</td>
    <td>1.03</td>
  </tr>
  <tr>
    <td>byteArrayEquals 16384</td>
    <td>25.536 us/op</td>
    <td>21.195 us/op</td>
    <td>1.20</td>
  </tr>
  <tr>
    <td>Buffer.compare 16384</td>
    <td>204.82 ns/op</td>
    <td>207.07 ns/op</td>
    <td>0.99</td>
  </tr>
  <tr>
    <td>byteArrayEquals 123687377</td>
    <td>194.46 ms/op</td>
    <td>166.95 ms/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>Buffer.compare 123687377</td>
    <td>7.6885 ms/op</td>
    <td>7.1197 ms/op</td>
    <td>1.08</td>
  </tr>
  <tr>
    <td>byteArrayEquals 32 - diff last byte</td>
    <td>54.315 ns/op</td>
    <td>46.553 ns/op</td>
    <td>1.17</td>
  </tr>
  <tr>
    <td>Buffer.compare 32 - diff last byte</td>
    <td>17.793 ns/op</td>
    <td>16.436 ns/op</td>
    <td>1.08</td>
  </tr>
  <tr>
    <td>byteArrayEquals 1024 - diff last byte</td>
    <td>1.6554 us/op</td>
    <td>1.3052 us/op</td>
    <td>1.27</td>
  </tr>
  <tr>
    <td>Buffer.compare 1024 - diff last byte</td>
    <td>26.251 ns/op</td>
    <td>23.565 ns/op</td>
    <td>1.11</td>
  </tr>
  <tr>
    <td>byteArrayEquals 16384 - diff last byte</td>
    <td>26.011 us/op</td>
    <td>20.640 us/op</td>
    <td>1.26</td>
  </tr>
  <tr>
    <td>Buffer.compare 16384 - diff last byte</td>
    <td>202.09 ns/op</td>
    <td>176.32 ns/op</td>
    <td>1.15</td>
  </tr>
  <tr>
    <td>byteArrayEquals 123687377 - diff last byte</td>
    <td>194.48 ms/op</td>
    <td>163.60 ms/op</td>
    <td>1.19</td>
  </tr>
  <tr>
    <td>Buffer.compare 123687377 - diff last byte</td>
    <td>7.5915 ms/op</td>
    <td>9.6415 ms/op</td>
    <td>0.79</td>
  </tr>
  <tr>
    <td>byteArrayEquals 32 - random bytes</td>
    <td>5.2190 ns/op</td>
    <td>4.9300 ns/op</td>
    <td>1.06</td>
  </tr>
  <tr>
    <td>Buffer.compare 32 - random bytes</td>
    <td>17.460 ns/op</td>
    <td>15.830 ns/op</td>
    <td>1.10</td>
  </tr>
  <tr>
    <td>byteArrayEquals 1024 - random bytes</td>
    <td>5.2140 ns/op</td>
    <td>5.0340 ns/op</td>
    <td>1.04</td>
  </tr>
  <tr>
    <td>Buffer.compare 1024 - random bytes</td>
    <td>17.417 ns/op</td>
    <td>15.815 ns/op</td>
    <td>1.10</td>
  </tr>
  <tr>
    <td>byteArrayEquals 16384 - random bytes</td>
    <td>5.6130 ns/op</td>
    <td>5.0050 ns/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>Buffer.compare 16384 - random bytes</td>
    <td>17.562 ns/op</td>
    <td>22.686 ns/op</td>
    <td>0.77</td>
  </tr>
  <tr>
    <td>byteArrayEquals 123687377 - random bytes</td>
    <td>6.6500 ns/op</td>
    <td>10.240 ns/op</td>
    <td>0.65</td>
  </tr>
  <tr>
    <td>Buffer.compare 123687377 - random bytes</td>
    <td>19.170 ns/op</td>
    <td>33.440 ns/op</td>
    <td>0.57</td>
  </tr>
  <tr>
    <td>regular array get 100000 times</td>
    <td>34.238 us/op</td>
    <td>40.734 us/op</td>
    <td>0.84</td>
  </tr>
  <tr>
    <td>wrappedArray get 100000 times</td>
    <td>38.207 us/op</td>
    <td>49.918 us/op</td>
    <td>0.77</td>
  </tr>
  <tr>
    <td>arrayWithProxy get 100000 times</td>
    <td>13.577 ms/op</td>
    <td>10.859 ms/op</td>
    <td>1.25</td>
  </tr>
  <tr>
    <td>ssz.Root.equals</td>
    <td>47.672 ns/op</td>
    <td>54.911 ns/op</td>
    <td>0.87</td>
  </tr>
  <tr>
    <td>byteArrayEquals</td>
    <td>46.819 ns/op</td>
    <td>43.125 ns/op</td>
    <td>1.09</td>
  </tr>
  <tr>
    <td>Buffer.compare</td>
    <td>10.697 ns/op</td>
    <td>9.4700 ns/op</td>
    <td>1.13</td>
  </tr>
  <tr>
    <td>processSlot - 1 slots</td>
    <td>11.399 us/op</td>
    <td>12.978 us/op</td>
    <td>0.88</td>
  </tr>
  <tr>
    <td>processSlot - 32 slots</td>
    <td>2.0346 ms/op</td>
    <td>3.4530 ms/op</td>
    <td>0.59</td>
  </tr>
  <tr>
    <td>getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei</td>
    <td>59.292 ms/op</td>
    <td>82.452 ms/op</td>
    <td>0.72</td>
  </tr>
  <tr>
    <td>getCommitteeAssignments - req 1 vs - 250000 vc</td>
    <td>2.1578 ms/op</td>
    <td>2.5401 ms/op</td>
    <td>0.85</td>
  </tr>
  <tr>
    <td>getCommitteeAssignments - req 100 vs - 250000 vc</td>
    <td>4.1489 ms/op</td>
    <td>3.7027 ms/op</td>
    <td>1.12</td>
  </tr>
  <tr>
    <td>getCommitteeAssignments - req 1000 vs - 250000 vc</td>
    <td>4.4031 ms/op</td>
    <td>3.9718 ms/op</td>
    <td>1.11</td>
  </tr>
  <tr>
    <td>findModifiedValidators - 10000 modified validators</td>
    <td>751.32 ms/op</td>
    <td>1.7486  s/op</td>
    <td>0.43</td>
  </tr>
  <tr>
    <td>findModifiedValidators - 1000 modified validators</td>
    <td>734.91 ms/op</td>
    <td>755.65 ms/op</td>
    <td>0.97</td>
  </tr>
  <tr>
    <td>findModifiedValidators - 100 modified validators</td>
    <td>296.95 ms/op</td>
    <td>401.10 ms/op</td>
    <td>0.74</td>
  </tr>
  <tr>
    <td>findModifiedValidators - 10 modified validators</td>
    <td>187.36 ms/op</td>
    <td>150.59 ms/op</td>
    <td>1.24</td>
  </tr>
  <tr>
    <td>findModifiedValidators - 1 modified validators</td>
    <td>153.34 ms/op</td>
    <td>192.60 ms/op</td>
    <td>0.80</td>
  </tr>
  <tr>
    <td>findModifiedValidators - no difference</td>
    <td>153.57 ms/op</td>
    <td>265.49 ms/op</td>
    <td>0.58</td>
  </tr>
  <tr>
    <td>compare ViewDUs</td>
    <td>6.5974  s/op</td>
    <td>10.820  s/op</td>
    <td>0.61</td>
  </tr>
  <tr>
    <td>compare each validator Uint8Array</td>
    <td>2.0711  s/op</td>
    <td>2.0094  s/op</td>
    <td>1.03</td>
  </tr>
  <tr>
    <td>compare ViewDU to Uint8Array</td>
    <td>1.2607  s/op</td>
    <td>1.3203  s/op</td>
    <td>0.95</td>
  </tr>
  <tr>
    <td>migrate state 1000000 validators, 24 modified, 0 new</td>
    <td>836.60 ms/op</td>
    <td>1.0595  s/op</td>
    <td>0.79</td>
  </tr>
  <tr>
    <td>migrate state 1000000 validators, 1700 modified, 1000 new</td>
    <td>1.1009  s/op</td>
    <td>1.3726  s/op</td>
    <td>0.80</td>
  </tr>
  <tr>
    <td>migrate state 1000000 validators, 3400 modified, 2000 new</td>
    <td>1.3310  s/op</td>
    <td>1.5834  s/op</td>
    <td>0.84</td>
  </tr>
  <tr>
    <td>migrate state 1500000 validators, 24 modified, 0 new</td>
    <td>924.67 ms/op</td>
    <td>866.49 ms/op</td>
    <td>1.07</td>
  </tr>
  <tr>
    <td>migrate state 1500000 validators, 1700 modified, 1000 new</td>
    <td>1.1110  s/op</td>
    <td>1.1159  s/op</td>
    <td>1.00</td>
  </tr>
  <tr>
    <td>migrate state 1500000 validators, 3400 modified, 2000 new</td>
    <td>1.3370  s/op</td>
    <td>1.3605  s/op</td>
    <td>0.98</td>
  </tr>
  <tr>
    <td>RootCache.getBlockRootAtSlot - 250000 vs - 7PWei</td>
    <td>4.2700 ns/op</td>
    <td>5.9000 ns/op</td>
    <td>0.72</td>
  </tr>
  <tr>
    <td>state getBlockRootAtSlot - 250000 vs - 7PWei</td>
    <td>580.46 ns/op</td>
    <td>400.56 ns/op</td>
    <td>1.45</td>
  </tr>
  <tr>
    <td>naive computeProposerIndex 100000 validators</td>
    <td>50.894 ms/op</td>
    <td>60.336 ms/op</td>
    <td>0.84</td>
  </tr>
  <tr>
    <td>computeProposerIndex 100000 validators</td>
    <td>9.2606 ms/op</td>
    <td>8.8592 ms/op</td>
    <td>1.05</td>
  </tr>
  <tr>
    <td>naiveGetNextSyncCommitteeIndices 1000 validators</td>
    <td>8.1746  s/op</td>
    <td>8.4673  s/op</td>
    <td>0.97</td>
  </tr>
  <tr>
    <td>getNextSyncCommitteeIndices 1000 validators</td>
    <td>267.93 ms/op</td>
    <td>425.84 ms/op</td>
    <td>0.63</td>
  </tr>
  <tr>
    <td>naiveGetNextSyncCommitteeIndices 10000 validators</td>
    <td>9.0269  s/op</td>
    <td>9.2742  s/op</td>
    <td>0.97</td>
  </tr>
  <tr>
    <td>getNextSyncCommitteeIndices 10000 validators</td>
    <td>296.94 ms/op</td>
    <td>515.62 ms/op</td>
    <td>0.58</td>
  </tr>
  <tr>
    <td>naiveGetNextSyncCommitteeIndices 100000 validators</td>
    <td>9.6005  s/op</td>
    <td>12.007  s/op</td>
    <td>0.80</td>
  </tr>
  <tr>
    <td>getNextSyncCommitteeIndices 100000 validators</td>
    <td>245.72 ms/op</td>
    <td>307.62 ms/op</td>
    <td>0.80</td>
  </tr>
  <tr>
    <td>naive computeShuffledIndex 100000 validators</td>
    <td>32.975  s/op</td>
    <td>44.354  s/op</td>
    <td>0.74</td>
  </tr>
  <tr>
    <td>cached computeShuffledIndex 100000 validators</td>
    <td>1.0604  s/op</td>
    <td>559.45 ms/op</td>
    <td>1.90</td>
  </tr>
  <tr>
    <td>naive computeShuffledIndex 2000000 validators</td>
    <td>479.72  s/op</td>
    <td>385.64  s/op</td>
    <td>1.24</td>
  </tr>
  <tr>
    <td>cached computeShuffledIndex 2000000 validators</td>
    <td>35.426  s/op</td>
    <td>21.051  s/op</td>
    <td>1.68</td>
  </tr>
  <tr>
    <td>computeProposers - vc 250000</td>
    <td>10.124 ms/op</td>
    <td>8.4172 ms/op</td>
    <td>1.20</td>
  </tr>
  <tr>
    <td>computeEpochShuffling - vc 250000</td>
    <td>43.344 ms/op</td>
    <td>34.724 ms/op</td>
    <td>1.25</td>
  </tr>
  <tr>
    <td>getNextSyncCommittee - vc 250000</td>
    <td>160.43 ms/op</td>
    <td>121.35 ms/op</td>
    <td>1.32</td>
  </tr>
  <tr>
    <td>computeSigningRoot for AttestationData</td>
    <td>26.237 us/op</td>
    <td>16.150 us/op</td>
    <td>1.62</td>
  </tr>
  <tr>
    <td>hash AttestationData serialized data then Buffer.toString(base64)</td>
    <td>1.6616 us/op</td>
    <td>1.1734 us/op</td>
    <td>1.42</td>
  </tr>
  <tr>
    <td>toHexString serialized data</td>
    <td>1.3296 us/op</td>
    <td>965.29 ns/op</td>
    <td>1.38</td>
  </tr>
  <tr>
    <td>Buffer.toString(base64)</td>
    <td>164.28 ns/op</td>
    <td>116.05 ns/op</td>
    <td>1.42</td>
  </tr>
  <tr>
    <td>nodejs block root to RootHex using toHex</td>
    <td>140.50 ns/op</td>
    <td>119.91 ns/op</td>
    <td>1.17</td>
  </tr>
  <tr>
    <td>nodejs block root to RootHex using toRootHex</td>
    <td>89.706 ns/op</td>
    <td>77.528 ns/op</td>
    <td>1.16</td>
  </tr>
  <tr>
    <td>browser block root to RootHex using the deprecated toHexString</td>
    <td>229.80 ns/op</td>
    <td>184.81 ns/op</td>
    <td>1.24</td>
  </tr>
  <tr>
    <td>browser block root to RootHex using toHex</td>
    <td>174.72 ns/op</td>
    <td>153.26 ns/op</td>
    <td>1.14</td>
  </tr>
  <tr>
    <td>browser block root to RootHex using toRootHex</td>
    <td>162.69 ns/op</td>
    <td>141.66 ns/op</td>
    <td>1.15</td>
  </tr>
</tbody>
</table>


</details>



> by benchmarkbot/action
author_association: CONTRIBUTOR
user: login: twoeths
created_at: 2025-03-14T06:35:29Z
body: even with the fix, we still see randomly spike sometime, and it happens at different time on different node

<img width="1193" alt="Screenshot 2025-03-14 at 13 34 04" src="https://github.com/user-attachments/assets/1db8b49f-9308-4da4-9d0a-9add104af0f4" />

that's because of `gc` runs randomly when we have to create new tree for pending consolidation, similar to `processRewardsAndPenalties()`

author_association: CONTRIBUTOR
user: login: wemeetagain
created_at: 2025-03-19T16:28:48Z
body: :tada: This PR is included in [v1.28.0](https://github.com/ChainSafe/lodestar/releases/tag/v1.28.0) :tada:
author_association: MEMBER