Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize gas cost in for loop. #23

Closed
dbadoy opened this issue Jun 7, 2022 · 0 comments
Closed

Optimize gas cost in for loop. #23

dbadoy opened this issue Jun 7, 2022 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@dbadoy
Copy link
Contributor

dbadoy commented Jun 7, 2022

AS-IS

function getWhitelistAllowanceLeft(address wallet) external view returns (uint256 allowance) {
  uint256 length = _whitelist.length; // gas saving
  for (uint256 i; i != length;) {
      if (_whitelist[i] == wallet) {
          allowance++;
      }
      unchecked {
          ++i;
      }
  }

  return allowance;
}

function getWhitelistIndex(address wallet) external view returns (uint256) {
  uint256 length = _whitelist.length; // gas saving
  for (uint256 i; i != length;) {
      if (_whitelist[i] == wallet) {
          return i;
      }
      unchecked {
          ++i;
      }
  }

  revert DixelClubV2__NotWhitelisted();
}

That clone _whitelist from storage to use in loop is expected the effect of reducing SLOAD calls.

First, this is the test result.

address[20] addrs = [ ... ]

function origin() external {
    uint256 dummy = 0;
    uint256 len = addrs.length;
    for (uint256 i; i < len;) {
        if (addrs[i] == address(0)) {
            dummy += i;
        }
        unchecked {
            i++;
        }
    }
}

function suggest1() external {
    uint256 dummy = 0;
    address[] memory temp = addrs;
    uint256 len = temp.length;
    for (uint256 i; i < len;) {
        if (temp[i] == address(0)) {
            dummy += i;
        }
        unchecked {
            i++;
        }
    }
}

function suggest2() external {
    uint256 dummy = 0;
    address[] storage temp = addrs;
    uint256 len = temp.length;
    for (uint256 i; i < len;) {
        if (temp[i] == address(0)) {
            dummy += i;
        }
        unchecked {
            i++;
        }
    }
}
origin() gasUsed : 57873
suggest1() gasUsed : 43636
suggest2() gasUsed : 57925

suggest1() what clone storage data to memory variable seems to be the best case.


So, i suggest this.

TO-BE

function getWhitelistAllowanceLeft(address wallet) external view returns (uint256 allowance) {
    // gas saving
    address[] memory clone = _whitelist;
    uint256 length = clone.length;
    for (uint256 i; i != length;) {
        if (clone[i] == wallet) {
            allowance++;
        }
        unchecked {
            ++i;
        }
    }

    return allowance;
}

function getWhitelistIndex(address wallet) external view returns (uint256) {
    // gas saving
    address[] memory clone = _whitelist;
    uint256 length = clone.length;
    for (uint256 i; i != length;) {
        if (clone[i] == wallet) {
            return i;
        }
        unchecked {
            ++i;
        }
    }

    revert DixelClubV2__NotWhitelisted();
}
@sydneyitguy sydneyitguy added the enhancement New feature or request label Jun 8, 2022
@sydneyitguy sydneyitguy self-assigned this Jun 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

2 participants