Use Calldata Instead Of Memory For External Function Calls
Description
When a function with a memory
array is called externally, the abi.decode()
step has to use a for-loop to copy each index of the calldata
to the memory
index. Each iteration of this for-loop costs at least 60 gas (i.e. 60 * <mem_array>.length
). Using calldata
directly obviates the need for such a loop in the contract code and runtime execution.
Using calldata
instead of memory
can result in significant gas savings when the function is called externally, especially for larger arrays
Example Code
function foo(uint[] memory arr) external {
// Do something with arr
}
Here, foo
takes an array of unsigned integers as a memory parameter. When this function is called externally, the calldata
has to be copied to memory, which can result in higher gas usage.
By changing the function definition to use calldata
, the gas cost can be reduced:
function foo(uint[] calldata arr) external {
// Do something with arr
}
Recommendation
Consider using calldata
instead of memory
for function parameters that are expected to be called externally. This can result in significant gas savings, especially for larger arrays.