Skip to content

Instantly share code, notes, and snippets.

@ldcc
Last active May 24, 2019 02:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ldcc/565950a48f73d2ed217fbb1e9591531f to your computer and use it in GitHub Desktop.
Save ldcc/565950a48f73d2ed217fbb1e9591531f to your computer and use it in GitHub Desktop.
Solidity list structure gas consumption tests
pragma solidity ^0.4.24;
pragma experimental "v0.5.0";
contract ListSystematically {
struct Holder {
uint256 amount;
uint256 frees;
Share[] shares;
}
struct Share {
uint256 locks;
uint256 liftedPeriod;
}
mapping(address => Holder) internal holders;
// 140973 gas used of duplicate calls
// 427714 gas used of upgrade1
// 442714 gas used of upgrade ordering
function testSetHolder(uint256 locks, uint256 delays) public {
Holder storage h = holders[msg.sender];
h.amount = uint256(100000);
uint256 present = block.timestamp + delays;
uint256 len = h.amount / locks;
h.frees = h.amount - len * locks;
h.shares.length = len;
for (uint256 i = 0; i < len; i++) {
h.shares[i] = Share({locks : locks, liftedPeriod : present});
}
}
// when shares goes to be free ⇒
// gas 82394 when h.shares.length = 10
// gas 30428 when h.shares.length = 0
// otherwise ⇒
// gas 35768 when unlocks = 0
function testUpgrade1() public {
Holder storage h = holders[msg.sender];
uint256 unlocks = 0;
uint256 present = block.timestamp;
for (uint8 i = 0; i < h.shares.length; i++) {
if (h.shares[i].locks == 0) {
continue;
}
if (present >= h.shares[i].liftedPeriod) {
unlocks += h.shares[i].locks;
delete h.shares[i];
}
}
if (unlocks > 0) {
h.frees += unlocks;
}
}
// when shares goes to be free ⇒
// gas 81019 when h.shares.length = 10
// gas 21963 when h.shares.length = 0
// otherwise ⇒
// gas 140973 when unlocks = 0
function testUpgrade2() public {
Holder storage h = holders[msg.sender];
uint256 unlocks = 0;
uint256 counter = 0;
uint256 present = block.timestamp;
for (uint8 i = 0; i < h.shares.length; i++) {
if (present >= h.shares[i].liftedPeriod) {
unlocks += h.shares[i].locks;
} else {
h.shares[counter] = h.shares[i];
counter++;
}
}
if (unlocks > 0) {
h.frees += unlocks;
h.shares.length = counter;
}
}
// when shares goes to be free ⇒
// gas 78717 when h.shares.length = 10
// gas 27592 when h.shares.length = 0
// otherwise ⇒
// gas 302902 when unlocks = 0
function testUpgrade3() public {
Holder storage h = holders[msg.sender];
uint256 unlocks = 0;
uint256 present = block.timestamp;
Share[] memory shares = h.shares;
delete h.shares;
for (uint8 i = 0; i < shares.length; i++) {
if (present >= shares[i].liftedPeriod) {
unlocks += shares[i].locks;
} else {
h.shares.push(shares[i]);
}
}
if (unlocks > 0) {
h.frees += unlocks;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment