Solidity之为什么 ++i 比 i++ 省gas

为什么 ++i 比 i++ 省gas

i++通常更昂贵,因为它必须增加一个值并“返回”旧值,因此可能需要在内存中保存两个数字++我在记忆中只使用过一个数字。在许多情况下,在编译器优化之后,它们可能是等效的。

测试验证

demo1

为了验证,我在Remix中设置了两个合约:一个将使用i++,一个使用++i

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;


contract IteratorTest {

    uint256 i = 999;

    function increment() public {
        i++;
    }

    function retrieve() public view returns (uint256){
        return i;
    }
}

i++ 测试花费gas:30324 gas

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;


contract IteratorTest2 {

    uint256 i = 999;

    function increment() public {
        ++i;
    }

    function retrieve() public view returns (uint256){
        return i;
    }
}

++i 测试花费gas:30317 gas

总结:在两个合约中执行increment()函数。 i++ 测试花费gas:30324 gas,++i 测试花费gas:30317 gas。 ++i比 i++节省。

demo2

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;


contract IteratorTest3 {
    uint256[] public arr = [1, 2, 3, 4, 5];

    function find() public view returns (bool) {
        for (
            uint256 i = 0;
            i < arr.length;
            i++ /*++i*/
        ) {
            if (arr[i] == 5) {
                return true;
            }
        }
        return false;
    }
}

i++ 花费gas: 36221

在这里插入图片描述++i花费gas:36201
在这里插入图片描述

总结: i++ 花费gas: 36221,++i花费gas:36201,确实 ++i节省gas。

demo3

前面例子是状态变量,如下,我测试局部变量,测试结果一样,依旧是 ++i 比 i++ 省gas

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;


contract IteratorTest {


    function increment() public pure{
        uint256 enabledCount;
        uint256 count = 100;

        for (uint256 i = 0; i < count; i++) {
				enabledCount++;  // ++enabledCount;
		}


    }


}

为什么 ++i 比 i++ 省gas

原文地址:https://twitter.com/0xCygaar/status/1607860326271438848

作者使用debugger,对两者执行区别进行了分析:
i++ does actually save the original value before incrementing. We can see this behavior when stepping through our code. Here’s what the stack looked like for both contracts after the first section executed:

具体参考作者原文~

我做的第一件事是打开Remix debugger。对于那些不熟悉debugger的人,它是一种工具,可让您了解交易执行的每个EVM OPODE。

这就是为什么要知道assembly作为智能合约开发人员的重要性。

我主要使用指令面板(左中间,未命名)和堆栈面板(左下)。这些告诉我当时正在执行什么操作码以及堆栈的状态。
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西京刀客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值