ESSAY / NOTE

Gas优化方法实例

待优化代码 测试流程 部署合约 执行函数 [1, 2, 3, 4, 5, 100] 优化思路 1、减少冗余代码 2、优化参数、缓存可以缓存的参数
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

contract GasGolf {
    uint public total;

    // [1, 2, 3, 4, 5, 100]
    function sumIfEvenAndLessThan99(uint[] memory nums) external {
        for (uint i = 0; i < nums.length; i += 1) {
            bool isEven = nums[i] % 2 == 0;
            bool isLessThan99 = nums[i] < 99;
            if (isEven && isLessThan99) {
                total += nums[i];
            }
        }
    }
}
1、calldata 必须用于外部函数的动态参数。 只能用于函数声明参数,不能用于函数逻辑声明。 是不可变的,不能被覆盖和更改。 function sumIfEvenAndLessThan99(uint[] calldata nums) external 将memory替换为calldata 2、改变状态变量为在内存中
contract GasGolf {
    uint public total;

    function sumIfEvenAndLessThan99(uint[] calldata nums) external {
        uint _total = total;
        for (uint i = 0; i < nums.length; i += 1) {
            bool isEven = nums[i] % 2 == 0;
            bool isLessThan99 = nums[i] < 99;
            if (isEven && isLessThan99) {
                _total += nums[i];
            }
        }
        total = _total;
    }
}
3、布尔值优化短路
if (nums[i] % 2 == 0 && nums[i] < 99) {
                _total += nums[i];
            }
4、for换成++i
for (uint i = 0; i < len; ++i)
5、数组长度缓存、数组下标缓存
 uint len = nums.length;
 for (uint i = 0; i < len; ++i) {
            uint num = nums[i];
            if (num % 2 == 0 && num < 99) {
                _total += num;
            }
        }
优化完成的代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

contract GasGolf {
    // 看 execution cost GAS消耗
    // 初始状态 - 50908 GAS
    // calldata替换 - 49163 GAS 节省1745
    // 改变状态变量为在内存中 - 48952 GAS 节省211
    // 布尔值优化短路 - 48634 GAS  节省318
    // for换成++i - 48226 GAS 节省408
    // 数组长度缓存 - 48191 GAS 节省35
    // 数组下标缓存 - 48029 GAS 节省362
    uint public total;

    // [1, 2, 3, 4, 5, 100]
    function sumIfEvenAndLessThan99(uint[] calldata nums) external {
        uint _total = total;
        uint len = nums.length;
        for (uint i = 0; i < len; ++i) {
            uint num = nums[i];
            if (num % 2 == 0 && num < 99) {
                _total += num;
            }
        }
        total = _total;
    }
}