You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
keccak of calldata parameter takes extra 150gas for no apparent reason. a simple assembly wrapper can be used to demonstrate getting the same result for smaller cost.
This is a "low-hanging fruit" optimization. There are other places like this.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "hardhat/console.sol";
//deploy this contract to run the 2 tests
contract Asd {
constructor() {
bytes memory d = "A";
new Test().work2(d);
new Test().work1(d);
}
}
contract Test {
function calldataKeccak(bytes calldata data) internal pure returns (bytes32 ret) {
assembly {
let mem := mload(0x40)
let len := data.length
calldatacopy(mem, data.offset, len)
ret := keccak256(mem, len)
}
}
function work1(bytes calldata input) external view {
uint g= gasleft();
bytes32 data = keccak256(input);
uint g1 = gasleft();
console.logBytes32(data);
console.log('gas used', g-g1);
}
function work2(bytes calldata input) external view {
uint g= gasleft();
bytes32 data = calldataKeccak(input);
uint g1 = gasleft();
console.logBytes32(data);
console.log('gas used', g-g1);
}
}
The text was updated successfully, but these errors were encountered:
Hi @drortirosh thanks for reporting this. Please, consider the snippets below extracted from your example, ignoring the console.log() part:
sol-keccak.sol
contractTest {
function run(bytescalldatadata) externalpurereturns (bytes32ret) {
ret =keccak256(data);
}
}
yul-keccak.sol
contractTest {
function run(bytescalldatadata) externalpurereturns (bytes32ret) {
assembly {
let mem :=mload(0x40)
let len := data.lengthcalldatacopy(mem, data.offset, len)
ret :=keccak256(mem, len)
}
}
}
If you run each of them using --ir-optimized compiler flag (e.g. solc --ir-optimized sol-keccak.sol), you will notice that the extra gas usage shown above comes from the fact that the Solidity code is doing proper memory allocation for the array and the assembly snippet is not. It does not move the free memory pointer or allocate a size field for the array.
This is an already know issue and it is similar to the following ones:
Optimizing this falls under #13722 which is already in our roadmap. So, I will be closing this issue as duplicated. Please, feel free to reopen it if necessary.
Consider the following Remix sample.
keccak of
calldata
parameter takes extra 150gas for no apparent reason. a simple assembly wrapper can be used to demonstrate getting the same result for smaller cost.This is a "low-hanging fruit" optimization. There are other places like this.
The text was updated successfully, but these errors were encountered: