ssz
ssz copied to clipboard
createTreeBackedFromStruct performance
To research potential improvements I've written a manual createTreeBackedFromStruct() function for the validator object
const pubkey_n4 = new LeafNode(validator.pubkey.slice(0, 32));
const pubkey_n5 = new LeafNode(validator.pubkey.slice(32, 64));
const pubkey_n6 = new LeafNode(validator.pubkey.slice(64, 96));
const pubkey_n2 = new BranchNode(pubkey_n4, pubkey_n5);
const pubkey_n3 = new BranchNode(pubkey_n6, zeroNode(0));
const pubkey_n1 = new BranchNode(pubkey_n2, pubkey_n3);
const v_8 = pubkey_n1;
const v_9 = new LeafNode(validator.withdrawalCredentials);
const v_10 = new LeafNode(bigintToBuffer(validator.effectiveBalance));
const v_11 = new LeafNode(bigintToBuffer(validator.activationEligibilityEpoch));
const v_12 = new LeafNode(bigintToBuffer(validator.activationEpoch));
const v_13 = new LeafNode(bigintToBuffer(validator.exitEpoch));
const v_14 = new LeafNode(bigintToBuffer(validator.withdrawableEpoch));
const v_4 = new BranchNode(v_8, v_9);
const v_5 = new BranchNode(v_10, v_11);
const v_6 = new BranchNode(v_12, v_13);
const v_7 = new BranchNode(v_14, zeroNode(0));
const v_2 = new BranchNode(v_4, v_5);
const v_3 = new BranchNode(v_6, v_7);
const v_1 = new BranchNode(v_2, v_3);
const tree = new Tree(v_1);
Also a variation where the epoch fields are Numbers
...
const v_10 = new LeafNode(numToBuffer(validatorNum.effectiveBalance));
const v_11 = new LeafNode(numToBuffer(validatorNum.activationEligibilityEpoch));
const v_12 = new LeafNode(numToBuffer(validatorNum.activationEpoch));
const v_13 = new LeafNode(numToBuffer(validatorNum.exitEpoch));
const v_14 = new LeafNode(numToBuffer(validatorNum.withdrawableEpoch));
....
Results show that createTreeBackedFromStruct can be significantly improved.
✓ Validator - createTreeBackedFromStruct 193760.9 ops/s 6.161000 us/op - 183164 runs 1.01 s
✓ Validator - custom to tree bigint 376222.7 ops/s 2.658000 us/op - 343743 runs 1.02 s
✓ Validator - custom to tree number 658761.5 ops/s 1.518000 us/op - 557524 runs 1.02 s
Looking at profiles of this custom to tree functions most of the time is spent:
- slicing the Buffer
- doing bit ops on the numbers to convert them to buffers
I'm not sure if we can improve them any more, but occasionally updating a few validators (~100) would cost less than 1 ms.
CC: @wemeetagain