Gas
Solidity 是否記憶體了對內部純函式的呼叫?
我的一個庫函式呼叫另一個內部純函式,如下所示:
library MyLibrary { function foo(uint256 x) internal pure returns (uint256 result) { // do important work } function bar(uint256 x) public pure returns (uint256 result) { // ... uint256 foo_value = foo(x); } }
但是
foo
身體很小,所以我想如果我不叫它怎麼辦?我會省油嗎?library MyLibrary { function foo(uint256 x) internal pure returns (uint256 result) { // do important work } function bar(uint256 x) public pure returns (uint256 result) { // ... uint256 foo_value; // do important work here instead of in "foo" } }
但是不,我不會節省汽油。兩種實現的成本相同。這是為什麼?
可能對編譯細節有更深入了解的人會更準確地插話。
直覺上,人們可能會認為會有細微的差別來解釋跳轉到另一段程式碼、打包返回參數和解包接收到的參數的額外步驟,以及將值分配給
foo_value
. 差異可以忽略不計。在實踐中,我懷疑編譯器正在“展開”該
pure
函式,因此它編譯時就好像它實際上是“內聯”編寫的。這就是您在第二個範例中在原始碼級別提出的建議,編譯器可能會為您執行此操作。如果是這樣的話,人們會期望沒有區別或幾乎沒有區別。如果您想深入研究它,您可能會使用像 Remix 的內置工具這樣的調試器來單步執行程式碼並在發生字節碼時觀察它。它們可能完全相同,也可能具有相似成本的微小差異。我想要關注的重要因素是第一個範例是否有額外的 JUMP 操作碼可以跳入並返回,或者它是否以線性方式進行,而無需您提供額外的“幫助”。
在實踐中,通常需要對編譯器有“足夠深入”的了解才能知道重要的區別可能在哪裡,並通過實驗找出哪種方式更好。事實上,結果有時令人驚訝。
希望能幫助到你。