ssz icon indicating copy to clipboard operation
ssz copied to clipboard

createTreeBackedFromStruct performance

Open dapplion opened this issue 3 years ago • 0 comments

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

Screenshot from 2021-08-03 22-31-04 Screenshot from 2021-08-03 22-31-26

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

dapplion avatar Aug 03 '21 20:08 dapplion