Skip to content

Fast method for calculating transaction size

Luke Champine requested to merge txn-size into master

The transaction pool makes frequent use of the size of encoded transactions. Currently, we determine the size of a transaction by writing its encoded form to a buffer and returning the length of the buffer. Even though the transaction type has a custom MarshalSia method, this is still wasteful; it is slow and puts pressure on the garbage collector.

The transaction type (and a few others) now have a MarshalSiaSize method that returns the encoded size without encoding anything. These methods are essentially just iterated arithmetic, so they run very fast. Benchmarks for encoding types.GenesisBlock.Transactions[0]:

BenchmarkTransactionMarshalSiaSize-4   	2000000     918 ns/op      0 B/op     0 allocs/op
BenchmarkTransactionMarshalSiaLen-4    	 100000   12078 ns/op  11144 B/op   205 allocs/op

(BenchmarkTransactionMarshalSiaLen calls len(encoding.Marshal(txn))) For small transactions, the effect is more pronounced: up to 40x faster.

I also added MarshalSia methods for types.FileContract and types.FileContractRevision. This definitely speeds up the encoding of a transaction, but the effect isn't visible when encoding the genesis transaction (since it doesn't contain any file contracts).

Merge request reports