我试图通过优化代码来节省气体。但是,我想知道,从阵列到固体阵列复制到阵列的最佳实践是什么。
我提出了两个选项。一个是通过指针复制(我猜),另一个正在使用循环。
TestOne.sol
contract TestContract {
uint32[4] testArray;
constructor(uint32[4] memory seeds) {
testArray = seeds; // execution costs: 152253
}
function Show() public returns (uint32[4] memory) {
return testArray;
}
}
TestTwo.sol
contract TestContract {
uint32[4] testArray;
constructor(uint32[4] memory seeds) {
for(uint i = 0; i < 4; i++) {
testArray[i] = seeds[i]; // execution costs: 150792
}
}
function Show() public returns (uint32[4] memory) {
return testArray;
}
}
I tested with Remix (Ethereum Online IDE), 0.8.13 Solidity Compiler with Enable optimization (200)
Discussion of test result
We can see that, Testone使用 152253 GAS 用于执行成本,而Testwo使用 150792 GAS 用于执行成本。
有趣的是, for-loop 使用的气体少于分配指针。在我的小想法中,循环比另一个要多。 (至少有分配 uint I
,替换4次,检查条件4次(是否 i&lt; 4
),增加 i ++
4次等)
我怀疑坚固性编译器的“优化”。但是,在没有“启用优化”的情况下进行相同的小实验后,它也会产生同样的结果,即循环使用较少的气体。 (198846 vs. 198464)
问题是
为什么上述事情发生了?
-
从数组到数组复制的最佳实践是什么?是否有任何复制功能,例如C ++'S std :: copy()
?
I am trying to save gas by optimize code. In a flash, however, I was wondered what is the best practice of copying from array to array in Solidity.
I present two option. One is copying by pointer (I guess) and the other is using for-loop.
TestOne.sol
contract TestContract {
uint32[4] testArray;
constructor(uint32[4] memory seeds) {
testArray = seeds; // execution costs: 152253
}
function Show() public returns (uint32[4] memory) {
return testArray;
}
}
TestTwo.sol
contract TestContract {
uint32[4] testArray;
constructor(uint32[4] memory seeds) {
for(uint i = 0; i < 4; i++) {
testArray[i] = seeds[i]; // execution costs: 150792
}
}
function Show() public returns (uint32[4] memory) {
return testArray;
}
}
I tested with Remix (Ethereum Online IDE), 0.8.13 Solidity Compiler with Enable optimization (200)
Discussion of test result
We can see that, TestOne used 152253 gas for execution costs, and TestTwo used 150792 gas for execution costs.
The funny thing is that, for-loop used less gas than just assigning pointer. In my little thought, for-loop would be more assembly codes than the other. (There would be, at least, assigning uint i
, substitute 4 times, check conditions 4 times (whether i < 4
), increase i++
4 times etc.)
I suspected the "optimization" of solidity compiler. But, after doing same small experiment without "Enable optimization", it does same result that for-loop used less gas. (198846 vs. 198464)
The Question is
-
Why do above things happened?
-
What is the best practice of copying from array to array? Is there any copy function like C++'s std::copy()
?
发布评论
评论(1)
最佳实践是将数组从内存到存储,而无需循环浏览其项目。但是,在此示例中的合同优化是棘手的。 官方文档
要在上面说明上面的说明,请考虑以下合同:
使用
布朗尼
:以下
Brownie-config.yaml
:给出以下输出:
得出以下结论
使用的气体
从函数 setArrayWithOutloop 和functionsetArrayWithloop
。The best practice is copy array from memory to storage without looping over their items. However contract optimization in this example is tricky. The official documentation says as follow:
To illustrate above, consider following contracts:
and script written by using
brownie
:with following
brownie-config.yaml
:which gives following outputs:
Conclusions
gas used
from functionsetArrayWithoutLoop
and functionsetArrayWithLoop
.