solidity文档中提到,如果幂运算的指数较小时,使用连乘会更节约gas,那这个临界值在哪呢,幂运算的指数到多少之后会比连乘节约gas呢?能节约多少呢,毕竟蚊子腿也是肉
solidity 文档中提到,如果幂运算的指数较小时,使用连乘会更节约 gas ,那这个临界值在哪呢,幂运算的指数到多少之后会比连乘节约 gas 呢?能节约多少呢,毕竟蚊子腿也是肉
在“checked” 模式下,幂运算仅会为小基数使用相对便宜的
exp
操作码。 例如x**3
的例子,表达式x*x*x
也许更便宜。 在任何情况下,都建议进行 gas 消耗测试和使用优化器。
Gas 消耗计算方法参考:计算Solidity 函数的Gas 消耗。使用 Hardhat 进行测试。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Strings.sol";
interface IGasCostTest{
function setX() external;
function setY() external;
}
contract GasCostTest{
uint256 public x = 2;
uint256 public y = 2;
function setX() external {
x = x ** 9;
}
function setY() external {
y = y * y * y * y * y * y * y * y * y;
}
}
contract CalculateGasCost {
string public report;
IGasCostTest public TestAddress;
constructor(address testAddress_){
TestAddress = IGasCostTest(testAddress_);
}
function GasCost(
string memory name,
function() external fun
) public {
uint256 u0 = gasleft();
fun();
uint256 u1 = gasleft();
uint256 diff = u0 - u1;
string memory s = report;
report = string(abi.encodePacked(s, string(abi.encodePacked(name, " GasCost: ", Strings.toString(diff))), "\n"));
}
function GenReport() public {
GasCost("setX ", TestAddress.setX);
GasCost("setY ", TestAddress.setY);
}
}
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Test x ^ 9", function () {
let ContractAddress, CalculateGasCostAddress;
before('布署合约', async function () {
const ContractInstance = await ethers.getContractFactory("GasCostTest");
const CalculateGasCostInstance = await ethers.getContractFactory("CalculateGasCost");
ContractAddress = await ContractInstance.deploy();
CalculateGasCostAddress = await CalculateGasCostInstance.deploy(ContractAddress.address);
});
it("CalculateGasCost", async function () {
await CalculateGasCostAddress.GenReport();
await CalculateGasCostAddress.GenReport();
const res = await CalculateGasCostAddress.report();
console.log(res);
const x = await ContractAddress.x();
const y = await ContractAddress.y();
expect(x).to.equal(y);
});
});
Test x ^ 3
setX GasCost: 8446
setY GasCost: 6202
setX GasCost: 8492
setY GasCost: 6202
Test x ^ 9
setX GasCost: 8446
setY GasCost: 8314
setX GasCost: 9073
setY GasCost: 8314
Test x ^ 10
setX GasCost: 8446
setY GasCost: 8666
setX GasCost: 9073
setY GasCost: 8666
Test x ^ 3
setX GasCost: 8242
setY GasCost: 5674
setX GasCost: 8345
setY GasCost: 5674
# 因为会导致 uint256 溢出,所以只执行一次
Test x ^ 30
setX GasCost: 8242
setY GasCost: 8239
Test x ^ 31
setX GasCost: 8242
setY GasCost: 8334
# 未使用 remix 优化器:
Test 1 << 3
setX GasCost: 8468
setZ GasCost: 5520
Test 1 << 250
setX GasCost: 8468
setZ GasCost: 5529
# 使用 remix 优化器:
Test 1 << 3
setX GasCost: 8264
setZ GasCost: 5500
Test 1 << 250
setX GasCost: 8264
setZ GasCost: 5506
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!