crates/lint/docs/cache-array-length.md
Severity: Gas
ID: cache-array-length
Flags for loop conditions that read a storage dynamic array's .length on every iteration
instead of comparing against a cached local length.
Reports comparison expressions in for loop conditions when either side reads .length from a
state dynamic array, such as i < values.length or values.length > i, including comparisons
nested inside && / || conditions.
The lint does not report loops that already compare against a local cached length variable.
It also skips loops that mutate an array length in the loop body, such as calling push() or
pop(), because aliases can make caching the length change the loop semantics.
Fixed-size arrays are excluded because their length is a compile-time constant instead of a repeated
dynamic length lookup. This lint currently checks for loops.
Reading .length in the loop condition repeats the storage length lookup for every iteration.
Caching the length once before entering the loop avoids repeated storage reads and can reduce gas
for hot loops.
contract C {
uint256[] values;
function sum() external view returns (uint256 total) {
for (uint256 i = 0; i < values.length; ++i) {
total += values[i];
}
}
}
contract C {
uint256[] values;
function sum() external view returns (uint256 total) {
uint256 length = values.length;
for (uint256 i = 0; i < length; ++i) {
total += values[i];
}
}
}
This is a Gas-severity lint and is not applied to test or script files.