Optimize existing and add missing Hash
implementations
#7238
+1,661
−458
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR:
std::hash::Hash
implementations in thestd
, for bytecode size and gas usage. The optimizations are based on eliminations of intensive memory allocations and memory copying. On a sample application, the bytcode size reduction was ~10%, and the gas usage reduction >50%. The detailed results are presented below.Bytes::append
on empty targetBytes
can lead to content/memory overrides #7234Hash
implementations for:()
,(T, )
,[T; 0]
,std
types that were missingHash
implementations, like, e.g.:Duration
,Time
,U128
,B512
, etc. Note thatHash
implementations were not provided for various Error enums.Performance Optimizations
To measure performance gains, a sample application was used, that:
Bytes
andVec
.Hasher
, simulating hashing of complex types like, e.g., structs.The bytcode size of the sample application got reduced from 9560 to 8584 bytes (10.21% reduction).
The overall gas usage for hashing types individually got reduced from 35826 to 15562 (56.56% reduction).
The overall gas usage for hashing types within a same
Hasher
got reduced from 34951 to 14443 (58.67% reduction).The
in_language
tests for hashing,hash_inline_tests
, also demonstrated a significant reduction in gas usage, up to 57.82%. A small regression is noticable when hashing empty types, e.g., unit. We expect that regression also to disappear onceconst fn
is implemented, and local constants could be evaluated from generic functions.Expand to see the detailed gas cost comparison for all `hash_inline_tests`
Breaking Changes
Strictly seen, adding
Hash
implementations forstd
types likeOption<T>
represents a breaking change for those who eventually had their own implementations. However, if such implementations existed, after introducing strict trait coherence checks, they already became invalid, because neither theHash
trait nor the typesHash
is implemented for are part of third party packages, but contained within thestd
.Thus, we can have a breaking change only if someone migrates from an older version that does not have trait coherence in place. But in that case, the trait coherence itself will already report breaking change errors.
Because
Hash
implementations forstd
types must and should have already been provided within thestd
, we can treat adding those implementations as a bug fix.Checklist
Breaking*
orNew Feature
labels where relevant.