How optimization works on solidity compiler?

Viewed 1826

I really can't figure out what the optimizer is in solidity, specifically the 'runs' parameter. I have set optimizer:true and left the default (200) on my truffle-config.js. This was the setting I used to deploy on eth mainnet. I deployed an erc20 governance token, a token that will serve for the life of the project. How does having runs:200 affect the gas cost for functions call of a token that will live years? should I have put a higher value? but in my opinion, any value is too low for a smartcontract that will live a long time. so what will my option at 200 entail? thanks

2 Answers

The number of runs (--optimize-runs) specifies roughly how often each opcode of the deployed code will be executed across the life-time of the contract.

Source: https://docs.soliditylang.org/en/v0.8.10/internals/optimizer.html#optimizer-parameter-runs

So if you're planning to have the contract invoked more than 200 times over the years, you might want to put in a larger count of runs. But there's a trade-off - a contract optimized for more (cheaper) runs is more expensive to deploy.

The goal of the optimizer is to generate assembly opcodes and, subsequently, machine code from high-level programming constructs in a way that reduces the gas cost during runtime.

Solidity optimizer basically splits the sequence of instructions into blocks of atomic instructions at JUMP s and JUMPDEST s opcodes. It operates on the assembly so that it can be used by other languages as well. An "atomic" operation is always observed to be done or not done, but never halfway done.

So these blocks are analyzed and every modification to memory, the stack, or storage is recorded as an expression. These expressions consist of an instruction and a list of arguments that are basically pointers to another expression. The main goal is to find equivalent expressions and group them into an expression class.

Basically, the code in each block is completely regenerated and a dependency graph is developed from such expressions. These expressions are then placed on the stack at the end of the block. Any operation that is not part of this dependency graph is essentially "removed". The code is now generated in the order they were present in the original solidity code. This applies to the modifications to memory and storage as well. Finally, all these values that are generated need to be on the stack in the correct place.

Related