kadenzipfel / gas-optimizations Goto Github PK
View Code? Open in Web Editor NEWList of smart contract optimizations in solidity
List of smart contract optimizations in solidity
Should add a section on this to https://github.com/kadenzipfel/gas-optimizations/blob/main/gas-saving-patterns/short-circuiting.md with this to leave the reader with a fully optimized statement
e.g. use
if (condition) {
if (anotherCondition) {
...
}
}
over
if (condition && anotherCondition) {...}
works for &&/||
Each gas optimization should have this information:
forge snapshot
to compare A/B testing. How much gas are we going to get? People will also be able to test with different config (solidity version, compile flags and so on)On proper-data-types.md file, this item:
Type uint256 takes less gas to store than uint8 (see why).
has the "see why" part, which seems to be a forgotten link/reference.
imo there exist two types of gas saving patterns:
we should create corresponding sections to separate these concerns
some things that can be added:
for technical gas saving patterns, e.g. https://github.com/KadenZipfel/gas-optimizations/blob/main/gas-saving-patterns/optimal-comparison-operator.md, in which the pattern works because of a solidity compilation gotcha, the mechanism in which gas is saved should be better detailed, e.g. by explaining which opcodes are removed and why
I believe the example for this optimization is not completely correct. Immutable should be used when the state variable is assigned in the constructor. If it is directly assigned in the declaration, then constant should be used. Not sure if it affects the gas used (which is the point of the repo), but I think that the example could make the point better if it assigns the variable in the constructor.
Another idea would be to show both cases (constant and immutable) in that section.
outline use of the new yul IR pipeline and how it may save gas
see: https://blog.soliditylang.org/2022/03/16/solidity-0.8.13-release-announcement/
outline usage of bit-packing using uints directly
The payable
modifier can also help to reduce deployment costs. You can cut out 10 opcodes in the creation-time EVM bytecode if you declare a constructor payable
. The following opcodes are cut out:
CALLVALUE
DUP1
ISZERO
PUSH2
JUMPI
PUSH1
DUP1
REVERT
JUMPDEST
POP
In Solidity, this chunk of assembly would mean the following:
if(msg.value != 0) revert();
I've compiled further gas optimisation tricks here.
Love this repository, but I think that there's an important piece of data missing from the code snippets: a Solidity pragma.
Gas costs differ between Solidity compiler versions, and in some cases the code may not even compile.
At the time of opening the issue, the Optimal Comparison Operator document makes the following claim:
In the case of a conditional statement, it is further optimal to use != when possible.
And then, the following gas costs are provided:
// 164 gas
function d() external pure {
require(1 > 0);
}
// 208 gas
function e() external pure {
require(1 >= 0);
}
// 120 gas
function f() external pure {
require(1 != 0);
}
In the first example below, each function execution will consume exactly 21,162 gas (with the function compare
per se consuming exactly 98 gas).
Try these on Remix with the optimizer enabled and set to 200 runs
pragma solidity =0.8.17;
contract A {
function compare() external pure {
require(1 > 0);
}
}
contract B {
function compare() external pure {
require(1 >= 0);
}
}
contract C {
function compare() external pure {
require(1 != 0);
}
}
And in this case, the reported gasUsed
will be 7.
pragma solidity =0.8.17;
contract A {
function compare(uint256 x) external view returns (uint256 gasUsed) {
uint256 startGas = gasleft();
if (x >= 0) {
uint256 foo = 1 + 2;
foo;
}
gasUsed = startGas - gasleft();
}
}
contract B {
function compare(uint256 x) external view returns (uint256 gasUsed) {
uint256 startGas = gasleft();
if (x > 0) {
uint256 foo = 1 + 2;
foo;
}
gasUsed = startGas - gasleft();
}
}
contract C {
function compare(uint256 x) external view returns (uint256 gasUsed) {
uint256 startGas = gasleft();
if (x != 0) {
uint256 foo = 1 + 2;
foo;
}
gasUsed = startGas - gasleft();
}
}
Let's start with this is what definitely isn't - this is not a matter of enabling the optimizer. Even with the optimizer disabled, the > 0
and != 0
checks cost the same in Solidity v0.8.17. That leaves with a couple of options left:
Whatever the case, as discussed in #3 and #15, the best way to avoid situations like this in the future would be to document the methodology that you used to obtain the reported gas costs, so that others can repeat your process and catch mistakes more easily.
we should make sure we have both:
for every gas saving pattern
in general, do while loops are cheaper than for loops. as long as the loop is must run at least once, do while is preferred over for loops
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.