I have a 1,300 loc project which is taking ~20s to compile in my M1 MAX. This is pretty high, right?
The performance really degraded recently as I added more types. It was taking ~8s when I was at 1,074 loc.
are you using a nightly build? or did you compile the compiler yourself?
Nightly from the 17th
ok. what sort of project is this?
there are some things in type checking that are slow. it does not surprise me, but it is disappointing that we run into issues so quickly
I ran roc build --time
and it looks like code gen takes 7s
. I'm a little confused reading the other sections as the times don't seem to add up to the totals.
yeah. Timing is weird because we run on multiple threads
can you share the --time
info?
sure
code gen time should not be influenced by adding more type annotations though
can you also share how long just a check
takes?
https://gist.github.com/agu-z/8eb15cb9f536a6bb9fcfeda55f9b963e
@Ayaz Hafiz check takes ~1.2s
can you share --time
for roc check
?
some of this is LLVM but it is a bit worrisome that some of these modules are taking ~0.5 seconds to check and >1second to generate the Roc-internal IR for.
roc check --time
https://gist.github.com/agu-z/456d02af60c236a9c0bba4a41639233a
ok. can you share this project?
Yep, it's a private repo now, but give me a min
https://github.com/agu-z/roc-pg
It depends on my fork of basic-cli
with sockets support: https://github.com/agu-z/roc-basic-cli/tree/sockets-support
A bunch of things lack type annotations and I'm using _
all the time while I'm figuring out how I want to do error handling. Maybe that has something to do with it.
I think that's unlikely, type annotations (or lack thereof) don't really change the computational complexity of the compiler
I think this somehow blows up specialization and the amount of copies of llvm ir we generate.
can you drop the flame graph in this chat @Brendan Hansknecht ? It might be off if it's not run with --max-threads=1
Was run with --max-threads=1
okay, we are spending all of our time doing occurs checks (checking and fixing recursive types)
in lambda sets, which makes sense
I have some ideas on how to deal with this. we added a bunch of caching to deal with this problem half a year ago but we can add even more
Do you now why it generates so much llvm ir?
probably the large # of lambda sets, not sure though
CleanShot-2023-04-06-at-17.23.092x.png
Not bad @Ayaz Hafiz!
Oh, and check
now takes 20ms
instead of 10s
!
the unreasonable effectiveness of a good properly placed cache :exhale:
even more impressive, the part of the build that was so slow went from over 100K ms to under 100ms, so...3 orders of magnitude improvement. :rocket: :rocket: :rocket:
which is relevant because the other 2 parts that make up almost all of that 6 seconds are linking and code generation, and the WIP surgical linking and dev backend projects should massively reduce those too
as a bit of anecdotal history: the last time we ran into something like this (~half a year ago) it took three weeks of full time effort (and one week of despair where nothing worked), and several major redesigns, to fix the problem. So this time around, the relatively simple effort, and knowledge of where else our gaps lie, is IMO a positive sign for the quality and maturity of the compiler.
moreover - it is exciting that folks like @Agus Zubiaga are getting the opportunity to stress the compiler in ways like this that actually expose where the faults are, and show how far the language has gotten!
Last updated: Jul 06 2025 at 12:14 UTC