-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add --no-gc
to crystal build
#14223
Comments
You can already do this using the BDWGC environment variable Example: $ GC_DONT_GC=1 time crystal build src/app.cr
1.36user 0.95system 0:01.91elapsed 121%CPU (0avgtext+0avgdata 518428maxresident)k
0inputs+9384outputs (0major+170188minor)pagefaults 0swaps
$ GC_DO_GC=1 time crystal build src/app.cr
2.18user 0.74system 0:02.52elapsed 115%CPU (0avgtext+0avgdata 399432maxresident)k
0inputs+9288outputs (0major+153022minor)pagefaults 0swaps As you can see, in this test I get about ~30% faster compilation (2.52s -> 1.91s) with ~30% increased max memory (399MB -> 518MB). |
Brilliant idea! I was using With the compiler |
I wonder if this shouldn't be the default, and have a |
@beta-ziliani Cool! Yea sometime last year we found that this helps majorly in building Kagi's web server, bringing some of our dev's times down from 5mins -> 2mins (2.5-1min in my personal case). As a hint, I did some profiling with |
When compiling Benben, I get these numbers on my laptop (Ryzen 3 3200U, I removed ~/.cache/crystal each time):
|
@MistressRemilia what are the times without it? |
@z64 That's an amazing finding 🤩 |
Test:
Stock Attribution of 40% cycles from PCRE finalizer: ( With the following patch applied: --- a/src/regex/pcre2.cr
+++ b/src/regex/pcre2.cr
@@ -254,12 +254,12 @@ module Regex::PCRE2
end
end
- def finalize
- @match_data.consume_each do |match_data|
- LibPCRE2.match_data_free(match_data)
- end
- LibPCRE2.code_free @re
- end
+ # def finalize
+ # @match_data.consume_each do |match_data|
+ # LibPCRE2.match_data_free(match_data)
+ # end
+ # LibPCRE2.code_free @re
+ # end
|
@beta-ziliani Without...? I have both GC_DO_GC and GC_DONT_GC there. Did I miss something 😅 |
@MistressRemilia You're executing your whole rakefile without GC, which can decrease performance dramatically. It probably:
Try to only show the difference in the final crystal build command |
Here's the result from Invidious with and without the cache: Without cache:
With cache:
Compiled with an AMD Ryzen 9 7950X |
@BlobCodes Crystal isn't compiling the Rakefile, that's a Ruby script. The way I have it written, it would first check that the Here are numbers calling the compiler directly on the same machine using the same command I have in my Rakefile for a release binary, they're pretty much the same numbers:
And without removing the cache:
Without the cache on my desktop (Core i9-10850K):
And with the cache:
|
Note that LLVM is of course not garbage collected. |
Even without --release I get at best a 1 second difference, cache or not. |
I made a patch that avoids using finalizers for libpcre2 and instead wires it up to normal GC. Unfortunately I am not observing any run time difference between these when using a release compiler to build a non-release compiler. (So disregard the commit message, it was hopeful 😅) |
Actually I am also not observing any difference if I just remove the |
Entirely possible something in our codebase has something the compiler is quite unhappy about WRT regex. I can't tell though from hotspot, can't follow the callers to any specific cause - will probably have to skim through IR. (Perhaps just too many literals, though I don't think we have that many really. We heavily discourage the use over regular string ops that are usually faster) |
Sorry! misread it. You're compiling in release mode, that explains those huge numbers! 😓 |
Adding this flag has been amazing for development for me. It has sped up the development compilation time enough that my Lucky app now compiles faster than the javascript build! (which takes over a minute itself...) However, I've noticed that as I save files and Lucky re-compiles the app, over the day I start losing memory. For example, I'll start with 30gb free, save and recompile about 10 times, then I'll have 28gb free. By the end of the day I'm sitting at 2gb free. I guess this is to be expected if garbage collecting isn't happening on each rebuild, but I figured I would at least report my findings. |
@jwoertink Hmm if the Crystal process exits, there should be no way that the memory use persists. If this is Linux (or if Mac is similar), make sure you're checking "available" memory rather than "free". Because the "free" memory metric in the |
This issue has been mentioned on Crystal Forum. There might be relevant details there: https://forum.crystal-lang.org/t/very-slow-build-speeds-for-hello-world/6881/12 |
Feature Request
Crystal build times can be slow, and the garbage collector can take up a significant portion of this time. This proposal is for a compile-time
--no-gc
flag that disables the garbage collector during compile-time to speed up compilation time at the cost of memory. This does not break backwards compatibility.The text was updated successfully, but these errors were encountered: