-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Description
evmasm::AssemblyItem::operator== is pretty hot, especially in the peephole optimizer:
solidity/libevmasm/AssemblyItem.h
Lines 248 to 252 in 08c4e0c
| /// Shortcut that avoids constructing an AssemblyItem just to perform the comparison. | |
| bool operator==(Instruction _instr) const | |
| { | |
| return hasInstruction() && instruction() == _instr; | |
| } |
This operator calls hasInstruction() twice, once in the actual operator, and the second time in the instruction() solAssert:
solidity/libevmasm/AssemblyItem.h
Line 218 in 08c4e0c
| solAssert(hasInstruction()); |
This is enough to show up in profiles. The solAssert should either be a debug-only assert, or operator== should not repeat the check by using m_instruction directly. I would prefer the former since operator== is not the only hot callsite for hasInstruction().
This function (instruction() calling hasInstruction()) is BY FAR the most time consuming operation in the evmasm optimizer.
This should be a single line change for an estimated E2E 5-10% performance improvement in optimized compilations.
On solady:
~/github/solady main !1 ?3 ❯ hyperfine -w1 --prepare 'forge clean' 'SOLC=solcd forge b' 'SOLC=solcd2 forge b' ✘ INT 18:34:21
Benchmark 1: SOLC=solcd forge b
Time (mean ± σ): 18.934 s ± 0.425 s [User: 17.609 s, System: 0.865 s]
Range (min … max): 18.657 s … 19.703 s 10 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.
Benchmark 2: SOLC=solcd2 forge b
Time (mean ± σ): 17.796 s ± 0.332 s [User: 16.329 s, System: 0.834 s]
Range (min … max): 17.639 s … 18.735 s 10 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.
Summary
SOLC=solcd2 forge b ran
1.06 ± 0.03 times faster than SOLC=solcd forge b
this is using a custom script as solc that uses the binary in the SOLC env var. this is the same as '--use X' in forge but i was using it for other profiling.
version 0.8.31-develop.2025.11.19+commit.08c4e0c6.mod.Darwin.appleclang (08c4e0c)
the diff for solcd and solcd2 is:
diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h
index dcb4bf3a7..59ebb7e15 100644
--- a/libevmasm/AssemblyItem.h
+++ b/libevmasm/AssemblyItem.h
@@ -215,7 +215,7 @@ public:
/// @returns the instruction of this item (only valid if hasInstruction returns true)
Instruction instruction() const
{
- solAssert(hasInstruction());
+ // solAssert(hasInstruction());
return *m_instruction;
}