Skip to content

Instantly share code, notes, and snippets.

@ewrvp7lv7
Last active February 13, 2022 10:58
Show Gist options
  • Save ewrvp7lv7/64549c6b487deb4308a6ba789487691a to your computer and use it in GitHub Desktop.
Save ewrvp7lv7/64549c6b487deb4308a6ba789487691a to your computer and use it in GitHub Desktop.
Ethereum gas optimization task

Etherium gas optimization task by the min function.

pragma solidity ^0.8.0;
contract MinContract {
    function min(uint256 a, uint256 b) public pure returns (uint256) {
        return a < b ? a : b;
    }
}

The result of the test task is the initial prototype

function min(uint256 a, uint256 b) public pure returns (uint256)

which called execution cost is less than the initial one for all admissible input values and the result of the execution coincides with the result of the execution of the initial one

Solution

Operation cost table in gas

Operation         Gas           Description

POP               2             Stack operation 
ADD/SUB           3             Arithmetic operation a + b, a - b
AND/OR/XOR        3             Bitwise logic operation
LT/GT/SLT/SGT/EQ  3             Comparison operation >, <
PUSH/DUP/SWAP     3             Stack operation
MLOAD/MSTORE      3             Memory operation
MUL/DIV           5             Arithmetic operation
ADDMOD/MULMOD     8             Arithmetic operation
JUMP              8             Unconditional jump
JUMPI             10            Conditional jump (if)
SLOAD             200           Storage operation
SSTORE            5,000/20,000  Storage operation
BALANCE           400           Get balance of an account
CREATE            32,000        Create a new account using CREATE
CALL              25,000        Create a new account using CALL

Thanks

Accordoing to Appendix G. Fee Schedu, Appendix H. Virtual Machine Specification we can see that MUL (*) gets 5, and JUMPI (if) gets 10 gas fee. Else, we should consider LT/GT (less/great) is only 3 gas and not equal JUMPI. That is why

//not work! because bool not convrrted to int
int i =(a< b); //i = 1 or 0
int ri = (i< 1);// reverce i
return i*a + ri*b;

more effective than if. But conversion bool to int more simple in asemble

pragma solidity ^0.8.0;

contract MinContract {

    function min(uint256 a, uint256 b) public view returns (uint256){
        assembly {
            let bcu := lt(a, b)//conversion
            mstore(0x0, add(mul(bcu, a), mul(lt(bcu, 1), b)))
            return(0x0, 32)
        }
        //return a < b ? a : b;
    }
}

TODO lt(bcu, 1) not best way to reverse bcu, but it more effective by binary way like ~bcu

Results

called execution cost gas fee

a, b 200, 100 100, 200 2000, 1000 100000, 200000
by operator ? 22131 22121 22155 22169
asm 21943 21943 21967 21991
a, b 15792089237316195423570985008687907853269984665640564039457584007913129639935, 5792089237316195423570985008687907853269984665640564039457584007913129639935
by operator ? 22875
asm 22687
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment