Solidity Optimization – Gas Difference Between Optimized vs Unoptimized Function Calls in Solidity

optimizationsolidity

I heard about optimize with run=200 then,

case1. first 200 call cost will be cheap

case2. the call over the 200 will be expensive.

If I don't use optimize, then Is the function call cost same with the case2? or Are all the calls cheaper than case2?

I tested the 3 cases with calling a same NFT minting function (this function has quite complicated logic, white list checking, erc20 token payment, etc..)

the environment is truffle local with config

compilers: {
    solc: {
      version: "0.8.7",      // Fetch exact version from solc-bin (default: truffle's version)
      settings: {          // See the solidity docs for advice about optimization and evmVersion
       evmVersion: "london",
       optimizer: {
         enabled: true|false,
         runs: 1|200
       },
      },
    }
  },

case1. unoptimized

   first call gas used: 194789
   second call gas used: 105801
   third call gas used: 105801

case2. optimized with run=1

   first call gas used: 191561
   second call gas used: 102766
   third call gas used: 102766

case3. optimized with run=200

   first call gas used: 190978
   second call gas used: 102183
   third call gas used: 102183

It seems that all the first call is expensive. and all next calls are same gas cost(and it is always cheaper than unoptimized!) even if run=1 (I tested this to 100th call and gas used is same).

Can anyone explain this behavior?

Best Answer

The first call is more expensive than the others due to changing storage values from zero to non-zero (SSTORE gas cost is higher in this case). The next calls probably all change values from non-zero to non-zero, hence they have the same lower cost. (This is all hypothetical since I can't see the contract source).

The optimizer helps reducing the overall cost of executing the contract. Fixing the state of the contract, i.e. the number of "calls" made so far, the expected gas cost is reduced by increasing the number of "runs".

I believe you're making the mistake of thinking that, for example, an optimizer with 200 runs helps only the first 200 calls. This isn't true, the number of calls is irrelevant since the state of the contract isn't known by the compiler.

Remember that increasing the runs has the drawback of increasing the deployment gas cost, it's important to find your sweet-spot number!

Related Topic