Gas metrics for dk1a/solidity-stringutils
This repo is for custom logging tests I use for my optimizations. Arachnid/solidity-stringutils is used as a baseline.
Clone the repo, in it run:
yarn install
forge test -vvv
Default forge gas snapshots can't really measure the efficiency of string/bytes functions, since
- it's not really well-suited for internal funcs
- they take dynamic inputs and have various caveats; e.g. for 1000-byte string finding an item at index
0
and index500
will have very different gas usage.
The logs can be hard to read. The gist of what I've learned so far:
- dk1a/solidity-stringutils seems very gas efficient, and it kind of is, except it could be way more efficient for short strings at the sacrifice of usability and readability
- Arachnid/solidity-stringutils isn't designed with solidity 0.8 in mind - no unchecked blocks means the gas use is very inflated. If you add
unchecked
everywhere, most methods become significantly more efficient, and outpace my lib for shortish strings. - I have a particularly fast inequality cmp for long strings. For 10000+ bytes
memcmp
is about as fast asmemeq
(i.e. just equality of keccak256 hashes, which is as fast as it gets). memchr
(and find and its downstream) work particularly well for any strings > ~8 bytes. (they're designed for long strings, and for 8-32 bytes memchr has binary search tricks; but no tricks for memrchr,rfind).- Shorter strings are worse mostly due to overhead. Like just calling len() and ptr() wastes ~50 gas everywhere. That's the "usability and readability" part that I'm reluctant to optimize away.
- memcmp, memchr, memmove etc are fast and have little overhead; you can use them directly if you need to.
- memmove (i.e. identity precompile) is great but is
view
; memcpy (i.e. chunked mload+mstore) is way worse but ispure
. I don't use memcpy internally, but it is there if you need it. This is why some methods in Slice and StrSlice are view. - StrCharsIter:
count
is kinda slow - it has to validate every single UTF-8 char.unsafeCount
is very fast - it doesn't validate anything. Note that arachnid'slen
has no validation and is the equivalent ofunsafeCount
.