我正在查看 uniswapv2 教程演练。
以下内容参考了github 存储库中的此函数,并且教程说明如下:
uint _kLast = kLast; // gas savings
Run Code Online (Sandbox Code Playgroud)
kLast 状态变量位于存储中,因此它在合约的不同调用之间会有一个值。访问存储比访问合约函数调用结束时释放的易失性内存要昂贵得多,因此我们使用内部变量来节省燃料。
因此,在传统编程中,_kLast
将引用kLast
. _kLast
实例化后又被引用 3 次。
kLast
变量,而不是将其分配给,那么每次使用uint
时是否都会花费一次存储读取?kLast
在交易期间,同一槽的每次存储读取(操作码sload
)第一次花费 2,100 Gas,然后在同一交易期间每次都花费 100 Gas。(柏林硬分叉实施EIP-2929之后。在此之前,无论执行多少次读取,每次读取都是800。)
每次内存写入(操作码mstore
)和每次内存读取(操作码mload
)都会花费 3 个 Gas。
所以在传统编程中,
_kLast
将引用kLast
在这个特定的 Solidity 片段中,_kLast
不是指向存储的引用。它是一个内存变量,具有从存储变量分配的值。
因此,3 次存储读取(不创建内存变量)将花费 2,300 Gas (= 2,100 + 100 + 100)。
但由于代码创建了内存变量,因此它执行一次存储读取 (2,100 Gas)、一次内存写入 (3 Gas) 和 3 次内存读取 (3 x 3 Gas) - 总计 2,112 Gas。这是一个更便宜的选择。
其他一些与 EVM 兼容的网络,例如 BSC,可能仍使用每个 800 的原始 Gas 计算sload
。这会产生更大的差异 - 未优化的 2,400 气体 (3 x 800) 和优化的 812 气体 (800 + 3 + 3x3)。
归档时间: |
|
查看次数: |
744 次 |
最近记录: |