if(num <= 10) revert();
And
if(num < 11) revert();
Which of these statements consume less gas?
If we could save gas, we need not use less than/greater than equal to. We can just use less than or greater than along with the next integer.
LE (lower or equal) opcode does not exist on EVM, the operation is accomplished as a combination of existing opcodes. The specific combination will depend on the compiler version, optimizer, and code context, etc.
In that specific example the opcode for
if(num <= 10) revert();
is
PUSH A push 10
DUP2 num
GT num>10
PUSH [tag] 15 tag if GT is true
JUMPI jump if true
and for
if(num < 11) revert();
is
PUSH A push 11
DUP2 num
LT num<11
ISZERO negate LT
PUSH [tag] 15 tag
JUMPI jump if true
So, using <
option will be 3 gas more expensive than using the <=
due to the extra ISZERO opcode. But, in some cases like
return num <= 10;
PUSH A 10
DUP3 num
GT num > 10
ISZERO negate GT
return num < 11;
PUSH B 11
DUP3 num
LT num < 11
Using <=
will be the one costing 3 more gas.
In conclusion, it depends on the code context which one is more efficient but, the 3-gas difference is negligible so, could consider using either.
The answer is not so straightforward. EVM has only the LT
opcode, so the two statements for operators <
and <=
are different. Therefore, the compiler should represent the <=
behavior with another flow. I thought the compiler would output the EQ
opcode additionally. But instead, a completely other bytecode is generated for the methods (num <= 10
/ num < 10
):
contract Foo {
function bar (uint num) external {
if (num <= 10) {
revert();
}
}
}
Click run
and compare the bytecode in some diff tools, the difference will be significant.
I executed bar
method tests locally (solidity 0.8.12
) for the versions of the contract with:
num < 10
num <= 10
num < 11
(just for ref)and got interesting results:
Values and Operator | Gas |
---|---|
8 < 10 | 21425 |
8 <= 10 | 21422 |
10 <= 10 | 21422 |
8 < 11 | 21425 |
10 < 11 | 21425 |
20 < 10 | 21431 |
20 <= 10 | 21428 |
20 < 11 | 21431 |
<=
consumed less gas in that contract example. Remember, that the optimizer could work differently for your codebase.