openzeppelin-contracts icon indicating copy to clipboard operation
openzeppelin-contracts copied to clipboard

Consider code duplication as optimization for EnumerableSet/Map

Open frangio opened this issue 5 years ago • 1 comments

Our implementation of EnumerableSet and EnumerableMap is using a kind of type erasure whereby the typed key/value is cast to and from bytes32, and the typed interface internally uses a set of functions that manipulate structures of bytes32. For example:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/394987f36527f16f85efdfbe9c944da629077917/contracts/utils/EnumerableSet.sol#L147-L149

A quick inspection showed that Solidity may not be inlining these internal calls, contributing to bytecode size and additional gas cost.

We should first confirm that this is the case.

I believe this is an optimization that should be done by the compiler, and we should report an issue. However, we may want to work around it in the meantime. A potential workaround would be to repeat the code for each new variant of the data structure (i.e. manual monomorphization). We should see whether this approach generates better code (smaller, less expensive).

frangio avatar Jun 01 '20 18:06 frangio

We are now doing code generation but retain the "type erasure" approach due to backwards compatibility of the storage layout (arguably a limitation of our Upgrades Plugins).

https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3429#issuecomment-1194551666

frangio avatar Sep 16 '22 20:09 frangio