Stage
The residual: wall minus the summed benchmarks stages. It is 11.2% of a uniswap compile and, on the projection in #720, most of the wall once the rest of the list has landed. Measured on an AMD Ryzen AI Max+ 395, 32 threads, 62 GB, Arch Linux 7.1.4: solx f85a40f, tree carrying only a release-debug profile in Cargo.toml, Release LLVM bdad05b, target/release/solx built 2026-09-19 00:28; warm, idle machine, first run discarded, --threads=1 --standard-json, six runs for wall and three for the probes.
Temporary Instant probes in a throwaway build account for it on uniswap, against a residual of 342.7 ms with the fixture's own selection and 133.6 ms with debugInfo deselected:
| Item |
Time |
Owner |
Output::get_debug_info |
209.1 ms |
#732 |
dropping the unselected AST in Build::write_to_standard_json |
109.8 ms over 160 entries |
#733 |
| process startup |
2.3 ms |
#728 |
Input::try_from, reading and parsing 1,581 KB |
1.9 ms |
— |
the contracts loop in write_to_standard_json |
0.9 ms |
— |
| pruning, serializing and writing the output |
0.4 ms |
— |
Input::resolve_sources, twice |
0.006 ms |
— |
Once the two issues that own the first two lines land, the residual is about 5 ms of real work plus process startup. Nothing here proposes to make it faster; there is nothing left in it.
Attribution
The four top-level timers in Compiler::standard_json_evm in solx-core/src/compiler.rs do not tile the process. Input::try_from runs before the first opens. Input::resolve_sources and Output::get_debug_info sit between the frontend timer and solx_BuildProject. After solx_Link closes, Build::write_to_standard_json in solx-core/src/build/mod.rs and Output::write_and_exit in solx-standard-json/src/output/mod.rs run untimed, and the second ends in std::process::exit, so nothing after it is measurable and no destructor runs.
Two items above 100 ms hid in that gap, neither of them named by any label, and both were found by bisecting output selectors rather than by reading. That is what this proposes to fix.
Fix
Bracket the gap with profiler entries and let the crate name them: input read and parse, source resolution, debug info, output construction, and output serialization. With those, wall minus the summed stages is process startup alone.
Expected
No change to wall. The unattributed time on uniswap goes from 342.7 ms to about the 2.3 ms that solx --version measures, and every input's unattributed time becomes a stage that a later issue can name.
Risk
Gas and size: none, the bytecode is byte-identical. Correctness: none, the change adds timers and reads no new state. Each timer is a few microseconds against stages measured in tens of milliseconds.
Verification
solx --threads=1 --standard-json on the uniswap and ENS fixtures, six runs each, warm, with benchmarks under the "" selector key: five new labels present, summing within the noise band of today's residual, the residual down to about 2.3 ms, wall unchanged within the noise band, and every contract's hex unchanged.
Decisions
None. The change buys no time, and the two issues that own the 318.9 ms it exposes buy it instead. It is worth taking anyway because the residual was 11.2% of a compile and neither item in it was visible from the compiler's own output.
Stage
The residual: wall minus the summed
benchmarksstages. It is 11.2% of a uniswap compile and, on the projection in #720, most of the wall once the rest of the list has landed. Measured on an AMD Ryzen AI Max+ 395, 32 threads, 62 GB, Arch Linux 7.1.4: solxf85a40f, tree carrying only arelease-debugprofile inCargo.toml, Release LLVMbdad05b,target/release/solxbuilt 2026-09-19 00:28; warm, idle machine, first run discarded,--threads=1 --standard-json, six runs for wall and three for the probes.Temporary
Instantprobes in a throwaway build account for it on uniswap, against a residual of 342.7 ms with the fixture's own selection and 133.6 ms withdebugInfodeselected:Output::get_debug_infoBuild::write_to_standard_jsonInput::try_from, reading and parsing 1,581 KBwrite_to_standard_jsonInput::resolve_sources, twiceOnce the two issues that own the first two lines land, the residual is about 5 ms of real work plus process startup. Nothing here proposes to make it faster; there is nothing left in it.
Attribution
The four top-level timers in
Compiler::standard_json_evminsolx-core/src/compiler.rsdo not tile the process.Input::try_fromruns before the first opens.Input::resolve_sourcesandOutput::get_debug_infosit between the frontend timer andsolx_BuildProject. Aftersolx_Linkcloses,Build::write_to_standard_jsoninsolx-core/src/build/mod.rsandOutput::write_and_exitinsolx-standard-json/src/output/mod.rsrun untimed, and the second ends instd::process::exit, so nothing after it is measurable and no destructor runs.Two items above 100 ms hid in that gap, neither of them named by any label, and both were found by bisecting output selectors rather than by reading. That is what this proposes to fix.
Fix
Bracket the gap with profiler entries and let the crate name them: input read and parse, source resolution, debug info, output construction, and output serialization. With those, wall minus the summed stages is process startup alone.
Expected
No change to wall. The unattributed time on uniswap goes from 342.7 ms to about the 2.3 ms that
solx --versionmeasures, and every input's unattributed time becomes a stage that a later issue can name.Risk
Gas and size: none, the bytecode is byte-identical. Correctness: none, the change adds timers and reads no new state. Each timer is a few microseconds against stages measured in tens of milliseconds.
Verification
solx --threads=1 --standard-jsonon the uniswap and ENS fixtures, six runs each, warm, withbenchmarksunder the""selector key: five new labels present, summing within the noise band of today's residual, the residual down to about 2.3 ms, wall unchanged within the noise band, and every contract's hex unchanged.Decisions
None. The change buys no time, and the two issues that own the 318.9 ms it exposes buy it instead. It is worth taking anyway because the residual was 11.2% of a compile and neither item in it was visible from the compiler's own output.