分配给 `uint` 如何在以太坊中节省 "storage read" 成本?
How does assigning to `uint` save "storage read" costs in Ethereum?
我正在看 uniswapv2 教程 walkthrough。
以下是参考此函数 in the github repo 并且教程说明如下:
uint _kLast = kLast; // gas savings
The kLast state variable is located in storage, so it will have a
value between different calls to the contract. Access to storage is a
lot more expensive than access to the volatile memory that is released
when the function call to the contract ends, so we use an internal
variable to save on gas.
所以在传统编程中,_kLast
将是对 kLast
的引用。 _kLast
在实例化后被引用了 3 次。
- 如果他们只使用
kLast
作为变量,而不是将其分配给 uint
,那么每次使用 kLast
都会花费存储读取吗?
- 如果不是这样,那我真的不明白他们是怎么省油的,有人能解释一下吗?
同一槽的每次存储读取(操作码sload
)在交易期间第一次花费 2,100 gas,然后在同一交易期间每次都花费 100 gas。 (柏林硬分叉实施EIP-2929之后。在此之前,不管读多少次,每次读都是800。)
每次内存写入(操作码mstore
)和每次内存读取(操作码mload
)花费3 gas。
So in traditional programming, _kLast
would be a reference to kLast
在这个特定的 Solidity 片段中,_kLast
不是指向存储的引用。它是一个内存变量,从存储变量中赋值。
所以 3 次存储读取 - 不创建内存变量 - 将花费 2,300 gas (= 2,100 + 100 + 100)。
但是因为代码创建了内存变量,它执行了一次存储读取(2,100 gas),一次内存写入(3 gas)和三次内存读取(3 x 3 gas) - 总共 2,112 gas。哪个更便宜。
其他一些与 EVM 兼容的网络,例如 BSC,可能仍使用每个 sload
800 的原始 gas 计算。这会产生更大的差异 - 未优化的 2,400 gas (3 x 800) 和优化的 812 gas (800 + 3 + 3x3)。
我正在看 uniswapv2 教程 walkthrough。
以下是参考此函数 in the github repo 并且教程说明如下:
uint _kLast = kLast; // gas savings
The kLast state variable is located in storage, so it will have a value between different calls to the contract. Access to storage is a lot more expensive than access to the volatile memory that is released when the function call to the contract ends, so we use an internal variable to save on gas.
所以在传统编程中,_kLast
将是对 kLast
的引用。 _kLast
在实例化后被引用了 3 次。
- 如果他们只使用
kLast
作为变量,而不是将其分配给uint
,那么每次使用kLast
都会花费存储读取吗? - 如果不是这样,那我真的不明白他们是怎么省油的,有人能解释一下吗?
同一槽的每次存储读取(操作码sload
)在交易期间第一次花费 2,100 gas,然后在同一交易期间每次都花费 100 gas。 (柏林硬分叉实施EIP-2929之后。在此之前,不管读多少次,每次读都是800。)
每次内存写入(操作码mstore
)和每次内存读取(操作码mload
)花费3 gas。
So in traditional programming,
_kLast
would be a reference tokLast
在这个特定的 Solidity 片段中,_kLast
不是指向存储的引用。它是一个内存变量,从存储变量中赋值。
所以 3 次存储读取 - 不创建内存变量 - 将花费 2,300 gas (= 2,100 + 100 + 100)。
但是因为代码创建了内存变量,它执行了一次存储读取(2,100 gas),一次内存写入(3 gas)和三次内存读取(3 x 3 gas) - 总共 2,112 gas。哪个更便宜。
其他一些与 EVM 兼容的网络,例如 BSC,可能仍使用每个 sload
800 的原始 gas 计算。这会产生更大的差异 - 未优化的 2,400 gas (3 x 800) 和优化的 812 gas (800 + 3 + 3x3)。