Open ilyapopov opened 2 years ago
Replacing Variant with tagged unions improves the time by ~20-30%, see experiment here, a large part of the remaining template instantiation time is spent resolving the conversion of runtime-known indices to types and v./v. for is Variant
.
Point two will be fixed by #1038 If you link that in the bullet-point it will auto check it when the PR is merged
The index lookup can be done in the compiler instead of using Variant::has
, that should speed things up a lot. note that the codegen is a bit confused as it tries to handle the case where the lhs of the is
operator is not an enum, but that is never the case at this point in the code
Turns out, -fno-exceptions
cuts about 2.7s (23%) from build time!
hyperfine -r 5 "cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literalsi jakt.cpp" "cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -fno-exceptions jakt.cpp"
Benchmark 1: cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literalsi jakt.cpp
Time (mean ± σ): 14.772 s ± 0.092 s [User: 14.208 s, System: 0.552 s]
Range (min … max): 14.666 s … 14.881 s 5 runs
Benchmark 2: cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -fno-exceptions jakt.cpp
Time (mean ± σ): 11.989 s ± 0.069 s [User: 11.431 s, System: 0.541 s]
Range (min … max): 11.874 s … 12.059 s 5 runs
Summary
'cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -fno-exceptions jakt.cpp' ran
1.23 ± 0.01 times faster than 'cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literalsi jakt.cpp'
Just have to make sure this does not break anything.
well, question is to we ever want to handle any c++ exceptions in jakt? i.e. in c++ extern blocks? if not then it is pretty sure ok
We don't do c++ exceptions here
We have our own Error
for that, which is supposed to be cheaper
Excellent initiative! For the Jakt part, make sure you build jakt
with optimizations (jakt -O
). It should run significantly faster than 0m4.788s
:^)
I have also analyzed the build using excellent ClangBuildAnalyzer
For the current master, the report looks like:
A lot of time is taken by visit
. After #1038, the report looks like
We don't do c++ exceptions here
We have our own
Error
for that, which is supposed to be cheaper
I understand that and am completely on your side. I am just saying disabling exceptions also means you cannot call throwing functions in extern c++ code, even if you directly surround them with a catch-all clause. It severely limits interoperability
Inside the serenity eco system that won't be an issue, but since a) serenity does have ports and you may wanna interact with non serenity libraries from jakt and b) this repo is separate and thus possibly also intended for non serenity use i thought this maybe something to consider
Serenity ports do not build with exceptions last I checked -- the Diablo port had to have them removed and replaced with assertions IIRC.
Serenity ports can choose to use whatever exception settings they like -- just if they end up interacting with Serenity native libraries (LibGUI for example), and they throw an exception through our libraries, we make no promises about what exception safety guarantees happens there. The C library has none, like basically every platform, and the STL is always either libc++
or libstdc++
. Normally GUI stuff is funneled through SDL2, which again, with a C API I would hope no one is passing callbacks that can throw an exception through SDL2 layers.
If someone really wants to call throwing C++ code from jakt... that seems out of scope for this performance issue anyway, and should be a different issue :^)
Jakt compiler is quite slow to compile. This slows down development of the language. Most of the time is spent in the Clang.
Currently on my machine:
Clang part
I have profiled this a little and saw some directions how compilation can be sped up:
Token
. It is aVariant
with ~100 alternatives, and is very slow to compile. Another one visible in the profile isCheckedExpression
. While other variants in the code are not that prominent in the profile individually, they probably take quite some time cumulatively. This suggests thatVariant
is a good candidate for optimization.debug_description
functions.debug_decription
fucntionsdebug_description
still usesVariant::visit
which is particularly slow to compile. Usage ofvisit
has already been removed from other parts of generated code (matches), so it can be removed from here too. PR: https://github.com/SerenityOS/jakt/pull/1038 by @Hendiadyoin1 --- -1s build time (-8%)debug_description
functions can be sped up by minimizing printing calls by merging them together.-fno-exceptions
https://github.com/SerenityOS/jakt/pull/1043 -2.7s (-23%)-fno-rtti
,-fno-unwind-tables
did not make any measurable differenceJakt part
I have not investigated that yet
Appendix
Profiling was done with clang with command line:
This generates
baseline.json
in thebuild
directory.Profile is attached: baseline.zip you can inspect it using Speedscope, Perfetto, Chrome dev tools, etc.