-
Notifications
You must be signed in to change notification settings - Fork 174
/
GasStorageLoad.t.sol
111 lines (86 loc) · 4.33 KB
/
GasStorageLoad.t.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import { Test } from "forge-std/Test.sol";
import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol";
import { Storage } from "../src/Storage.sol";
import { SolidityStorage, SomeContract } from "./Gas.t.sol";
contract GasStorageLoadTest is Test, GasReporter {
SomeContract someContract = new SomeContract();
// Cold loads require us to initialize the values outside of their test
function setUp() public {
(bytes32 valueSimple, bytes16 valuePartial, bytes memory value9Words) = SolidityStorage.generateValues();
(
SolidityStorage.LayoutSimple storage layoutSimple,
SolidityStorage.LayoutPartial storage layoutPartial,
SolidityStorage.LayoutBytes storage layoutBytes
) = SolidityStorage.layouts();
layoutSimple.value = valueSimple;
layoutPartial.value = valuePartial;
layoutBytes.value = value9Words;
}
function testCompareStorageLoadSolidity() public {
(bytes32 valueSimple, bytes16 valuePartial, bytes memory value9Words) = SolidityStorage.generateValues();
(
SolidityStorage.LayoutSimple storage layoutSimple,
SolidityStorage.LayoutPartial storage layoutPartial,
SolidityStorage.LayoutBytes storage layoutBytes
) = SolidityStorage.layouts();
startGasReport("solidity storage load (cold, 1 word)");
valueSimple = layoutSimple.value;
endGasReport();
startGasReport("solidity storage load (cold, 1 word, partial)");
valuePartial = layoutPartial.value;
endGasReport();
startGasReport("solidity storage load (cold, 10 words)");
value9Words = layoutBytes.value;
endGasReport();
// warm
startGasReport("solidity storage load (warm, 1 word)");
valueSimple = layoutSimple.value;
endGasReport();
startGasReport("solidity storage load (warm, 1 word, partial)");
valuePartial = layoutPartial.value;
endGasReport();
startGasReport("solidity storage load (warm, 10 words)");
value9Words = layoutBytes.value;
endGasReport();
// Do something in case the optimizer removes unused assignments
someContract.doSomethingWithBytes(abi.encode(valueSimple, valuePartial, value9Words));
}
function testCompareStorageLoadMUD() public {
(bytes32 valueSimple, bytes16 valuePartial, bytes memory value9Words) = SolidityStorage.generateValues();
bytes memory encodedSimple = abi.encodePacked(valueSimple);
bytes memory encodedPartial = abi.encodePacked(valuePartial);
bytes memory encoded9Words = abi.encodePacked(value9Words.length, value9Words);
bytes32 encodedFieldSimple = valueSimple;
bytes32 encodedFieldPartial = valuePartial;
startGasReport("MUD storage load (cold, 1 word)");
encodedSimple = Storage.load(SolidityStorage.STORAGE_SLOT_SIMPLE, encodedSimple.length, 0);
endGasReport();
startGasReport("MUD storage load (cold, 1 word, partial)");
encodedPartial = Storage.load(SolidityStorage.STORAGE_SLOT_PARTIAL, encodedPartial.length, 16);
endGasReport();
startGasReport("MUD storage load (cold, 10 words)");
encoded9Words = Storage.load(SolidityStorage.STORAGE_SLOT_BYTES, encoded9Words.length, 0);
endGasReport();
// warm
startGasReport("MUD storage load (warm, 1 word)");
encodedSimple = Storage.load(SolidityStorage.STORAGE_SLOT_SIMPLE, encodedSimple.length, 0);
endGasReport();
startGasReport("MUD storage load field (warm, 1 word)");
encodedFieldSimple = Storage.loadField(SolidityStorage.STORAGE_SLOT_SIMPLE, encodedSimple.length, 0);
endGasReport();
startGasReport("MUD storage load (warm, 1 word, partial)");
encodedPartial = Storage.load(SolidityStorage.STORAGE_SLOT_PARTIAL, encodedPartial.length, 16);
endGasReport();
encodedFieldPartial = Storage.loadField(SolidityStorage.STORAGE_SLOT_PARTIAL, encodedSimple.length, 16);
startGasReport("MUD storage load field (warm, 1 word, partial)");
encodedFieldPartial = Storage.loadField(SolidityStorage.STORAGE_SLOT_PARTIAL, encodedSimple.length, 16);
endGasReport();
startGasReport("MUD storage load (warm, 10 words)");
encoded9Words = Storage.load(SolidityStorage.STORAGE_SLOT_BYTES, encoded9Words.length, 0);
endGasReport();
// Do something in case the optimizer removes unused assignments
someContract.doSomethingWithBytes(abi.encode(encodedSimple, encodedPartial, encoded9Words));
}
}