[SAOC 2026] CTFE Performance Weekly Update #3
Abul Hossain Khan
abulkhan19175 at gmail.com
Mon Oct 12 20:02:31 UTC 2026
Hi everyone,
So last time I did the semantic upfront experiment. It worked but
it broke some valid code and couldn't handle virtual calls. So
this week I tried the other way round, and also added a CTFE
workload to the perf bot.
#### Semantic through a callback
The interpreter stays lazy, but it can only get semantic by
asking through a function it is given. One function pointer:
```d
alias CtfeSemantic = bool function(Dsymbol);
Expression ctfeInterpret(Expression e, CtfeSemantic semantic =
&frontendSemantic);
```
The default is the frontend's own code moved out of the
interpreter. The interpreter asks at the 4 places where it used
to call semantic itself, before running a function body and
before reading a constant that has no value yet. None of the 78
call sites change. Then a global check, any semantic that starts
during `ctfeInterpret` without going through the ask is counted,
and with `DMD_CTFE_CALLBACK=strict` it's an error.
| | test suite | Phobos unittests |
|---|--:|--:|
| asks for a function body / that had to analyse one | 133,597 /
3,274 | 5,172,111 / 1,885 |
| asks for a variable / that did real semantic | 75,245 / 13 |
165,190 / 30 |
| semantic outside the callback | 0 | 0 |
| failing with the check as an error | 0 of 3,926 | 0 of 166 |
So nothing runs semantic inside CTFE except through the ask. The
function one is the only one that really matters, the variable
one almost always finds the initializer already done. The valid
code that broke with the pre-pass compiles, and virtual calls
just work, the interpreter asks for the override once it has
picked it. One thing the engine has to allow is being entered
again while it waits for an ask, that happens 22,678 times in the
test suite.
Everything so far, the boundary, the probing, both experiments,
is here -
https://gist.github.com/abulgit/43f640a032c95557de959f7120d4fd69
#### CTFE workload in the perf bot
Thanks Dmitry for the suggestion. I took the default ctRegex
subset of `std/regex/internal/tests.d` compiled with `-unittest`.
It gets instructions, peak RSS, page faults and a time trace like
the other workloads.
PR Link - https://github.com/dlang/dmd/pull/24011 [Merged]
#### What's next
- Dennis filed a bunch of CTFE bugs his wasm experiment
uncovered. I'll be fixing those to get a better understanding of
the interpreter before writing the interface and all.
- A small code example for the rarer expression kinds going in
and out, in a separate gist.
- Have a deeper look at Steven's old CTFE engine, as he
suggested, to see what can be reused.
Thanks to Dennis for mentoring this. As always, feel free to
leave any feedback or suggestions!
More information about the Digitalmars-d
mailing list