You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been doing some performance testing of the new web3js on a sign-heavy workload. An example is create N signers, and then sign a transaction with all N signers M times.
At the extreme, there's a small performance regression between old web3js and new web3js:
Old:
Signed 100 transactions with 30 signers in 988 milliseconds
node index.mjs 30 100 1.38s user 0.07s system 106% cpu 1.361 total
New:
Signed 100 transactions with 30 signers in 1251 milliseconds
node index.mjs 30 100 1.73s user 0.07s system 103% cpu 1.735 total
(the time in the first line is just the signing (measured with performance.now inside the script), the second line is the output of time when running the script, so it has a longer total time since it includes eg generating the keypairs)
With fewer signers, we're faster:
Old:
Signed 100 transactions with 5 signers in 184 milliseconds
node index.mjs 5 100 0.50s user 0.03s system 75% cpu 0.712 total
New:
Signed 100 transactions with 5 signers in 89 milliseconds
node index.mjs 5 100 0.33s user 0.04s system 44% cpu 0.804 total
This made me suspect that there's a performance issue in our logic for signing. It shouldn't take >10x longer to sign with 6x more signers per transaction.
This is the issue: we're re-encoding the transaction message for every signer every loop.
If we modify this to call the getCompiledMessageEncoder().encode(message) in signTransaction only once, we see a massive performance improvement:
Signed 100 transactions with 30 signers in 120 milliseconds
node index.mjs 30 100 0.48s user 0.08s system 77% cpu 0.720 total
Signed 100 transactions with 5 signers in 44 milliseconds
node index.mjs 5 100 0.25s user 0.03s system 38% cpu 0.747 total
TLDR: We should refactor so that when you call signTransaction the getCompiledMessageEncoder().encode(message) call is only made once. This will unlock a massive performance improvement for sign-heavy workloads.
The text was updated successfully, but these errors were encountered:
Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up.
Overview
I've been doing some performance testing of the new web3js on a sign-heavy workload. An example is create N signers, and then sign a transaction with all N signers M times.
At the extreme, there's a small performance regression between old web3js and new web3js:
Old:
New:
(the time in the first line is just the signing (measured with
performance.now
inside the script), the second line is the output oftime
when running the script, so it has a longer total time since it includes eg generating the keypairs)With fewer signers, we're faster:
Old:
New:
This made me suspect that there's a performance issue in our logic for signing. It shouldn't take >10x longer to sign with 6x more signers per transaction.
The issue is here:
solana-web3.js/packages/transactions/src/signatures.ts
Lines 94 to 101 in 6910664
For each keypair, we are calling
getAddressFromPublicKey(keyPair.publicKey)
andgetCompiledMessageSignature(compiledMessage, keyPair.privateKey)
In
getCompiledMessageSignature
we encode the message:solana-web3.js/packages/transactions/src/signatures.ts
Lines 66 to 70 in 6910664
This is the issue: we're re-encoding the transaction message for every signer every loop.
If we modify this to call the
getCompiledMessageEncoder().encode(message)
insignTransaction
only once, we see a massive performance improvement:TLDR: We should refactor so that when you call
signTransaction
thegetCompiledMessageEncoder().encode(message)
call is only made once. This will unlock a massive performance improvement for sign-heavy workloads.The text was updated successfully, but these errors were encountered: