-
Notifications
You must be signed in to change notification settings - Fork 111
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
Faster startup #484
Faster startup #484
Conversation
Hi, this is the same code as Jeff added to Plots.jl, that I've been adding to other packages, except in your case I use Without (and even with) the startup was getting bad. Before you merge, be confident it's not a drawback at runtime (I doubt it is, but didn't test). I only noticed the time really after the new shorter "using Revise" for startup.jl. I see before, I've been benchmarking other code (including startup of julia), and including I guess influence of Revise in startup.jl... I know how not to, and personally, I'll change startup.jl to " Your package (but not all) also has the second
I'm a bit mystified why --startup-file=no isn't the default with julia -e "code". At least then Revise not needed, the only thing I use the file for. Can you think of a case where you would want it (the file) included? Should a PR be made at Julia? It's not like you can't ask for it on if you want. |
Setting this to zero turns of almost all optimizations which will likely make things quite slow. Using 1 might be OK
Just out of curiosity, what made you doubt it? |
Right, |
The latter commit has " I think each dependency is included for each package separately (e.g. one package could have a different version). Then I could see a theoretical possibility of a macro at the
Do you think it would be difficult to implement? |
Thanks for the PR! And sorry to be slow, I've been immersed in a pretty deep dive and keeping out of sight for a while. It's all falling into place so I can come up for air. For the record, I'm testing on a very recent Julia master (with a couple of custom commits, but they shouldn't affect anything) and if VERSION >= v"1.5.0-DEV.282"
try
using Revise
catch e
@warn(e.msg)
end
else
atreplinit() do repl
try
@eval using Revise
@async Revise.wait_steal_repl_backend()
catch e
@warn(e.msg)
end
end
end (on 1.5 you can just say On Revise master = v2.6.7 (which I see never made it to General due to DNS problems over the weekend), I get tim@diva:~/.julia/dev/Revise$ time julia-master -e "println(Revise)"
Revise
real 0m4.377s
user 0m4.411s
sys 0m0.260s which indeed is uncomfortably slow. With this PR, tim@diva:~/.julia/dev/Revise$ time julia-master -e "println(Revise)"
Revise
real 0m3.684s
user 0m3.788s
sys 0m0.188s which is indeed quite a lot nicer. A branch I'm working on and which should have a PR soon (it depends on JuliaDebug/LoweredCodeUtils.jl#30), I get tim@diva:~/.julia/dev/Revise$ time julia-master -e "println(Revise)"
Revise
real 0m1.629s
user 0m1.713s
sys 0m0.208s without this PR, and tim@diva:~/.julia/dev/Revise$ time julia-master -e "println(Revise)"
Revise
real 0m1.397s
user 0m1.454s
sys 0m0.229s with it. To be clear, currently I have no idea why that LoweredCodeUtils PR and the rewrite here is so consequential, but of course I'm very happy about it. And of course this PR improves things too, even on the upcoming faster version. Let's also check the runtime performance. I'm not sure of the best way to do this, but one option is to time tim@diva:~/.julia/dev/Revise/test$ time julia-master sigtest.jl
Test Summary: | Pass Total
:lambda expressions | 1 1
17.747128 seconds (51.45 M allocations: 1.919 GiB, 2.17% gc time)
real 0m25.426s
user 0m25.424s
sys 0m0.293s With this PR added, tim@diva:~/.julia/dev/Revise/test$ time julia-master sigtest.jl
Test Summary: | Pass Total
:lambda expressions | 1 1
17.342171 seconds (51.47 M allocations: 1.920 GiB, 2.18% gc time)
real 0m24.083s
user 0m24.135s
sys 0m0.240s so no performance hit. For fun I tried it on tim@diva:~/.julia/dev/Revise/test$ time julia-master sigtest.jl
Test Summary: | Pass Total
:lambda expressions | 1 1
17.939664 seconds (51.46 M allocations: 1.920 GiB, 2.21% gc time)
real 0m25.088s
user 0m25.063s
sys 0m0.320s which suggests even this should be safe (if my test is reasonable). On my upcoming branch, I get tim@diva:~/.julia/dev/Revise/test$ time julia-master sigtest.jl
Test Summary: | Pass Total
:lambda expressions | 1 1
14.656378 seconds (39.63 M allocations: 1.566 GiB, 2.95% gc time)
real 0m23.407s
user 0m23.437s
sys 0m0.264s without this PR, and tim@diva:~/.julia/dev/Revise/test$ time julia-master sigtest.jl
Test Summary: | Pass Total
:lambda expressions | 1 1
14.081439 seconds (39.64 M allocations: 1.566 GiB, 2.71% gc time)
real 0m22.380s
user 0m22.337s
sys 0m0.328s with it. Bottom line: this is a good change! I'm going to merge it. I'll register 2.6.7 as-is (without this PR), as it will be a useful benchmark for what I anticipate will be Revise 2.7.0 (which will include this and my PR). |
FYI: same startup file with
My 16-core, 128 GB, machine is somewhat (with firefox excl. sub-processes) taking 17% of memory. top - 15:44:59 up 32 days, 18:43, 1 user, load average: 11,00, 10,56, 8,86 sorted by VIRT (julia high, and slack, based on firefox): |
FYI, |
A. Is there a way to control/lower/eliminate other optimizations (without PackageCompiler)? I only know of inlining options, global and otherwise. I see Maybe aggressively adding B. FYI: I would not rule out using
those timings are for the latest Revise master, and I made sure to turn off firefox and some other programs. But Revise itself has a fixed lowered opt. (i.e. this is only for the dependencies of it; I didn't update) so I tried going to version 2.6.6 and then I get a bit more gap. |
Not really; there is
I doubt it; testing for inlineability doesn't take much time.
We don't yet save LLVM code; it would be nice to be able to do that. LLVM isn't source code though, e.g. it needs to be invalidated depending on what else has been loaded, might contain architecture-specific optimizations, etc. Also a huge amount of the time is in LLVM's native instruction selection, so for meaningful gains we probably need to save native code. |
I had totally forgotten about the (undocumented)
|
Revise's startup, and latency to first revision, is something I worry about a lot and am trying to address. I have quite a few local customizations that help (latest startup time for me is now 1.25s), but it's still not great: tim@diva:~/.julia/dev/Revise$ time julia-master -e 'includet("/home/tim/tmp/revise_data_code.jl")'
real 0m5.470s
user 0m5.500s
sys 0m0.264s with all my best tweaks, and tim@diva:~/.julia/dev/Revise$ time julia -e 'using Revise; includet("/home/tim/tmp/revise_data_code.jl")'
real 0m6.924s
user 0m7.014s
sys 0m0.204s on Julia 1.4 and tagged versions of packages. It's a less-impressive difference than I could have hoped but certainly still something to celebrate. I'd declare victory if I could get this down to about 1s, and we're a looong way from that. Without PackageCompiler I don't currently see a path to achieve that, unless (1) we can start caching LLVM or native code (and now that Revise is on the threshold of being completely non-invalidating, that's eliminated a major barrier), or (2) we start moving pieces of JuliaInterpreter/LoweredCodeUtils/Revise into Julia itself. To do that in a sensible way, (a) we'd probably need to merge JuliaInterpreter and If you had to pick (1) or (2), which seems more sensible? Obviously both are speculative and each is a big lift on its own. I don't know how to help with (1), but if it's not really on the table I think pretty soon we'll be in a position to contemplate (2). Revise still has some serious issues, but JuliaDebug/LoweredCodeUtils.jl#30 will likely be a game-changer. Exploiting it to its fullest will require a "contract" change for Revise that it will modify only methods and perhaps literal assignments like |
FYI: I did alias juli="~/julia-1.6.0-DEV-8f512f3f6d/bin/julia --compile=min -O1" for julia-interactive, I didn't want to alias julia, in case I forget... for benchmarking reasons, and changed startup to be as yours plus It makes startup tolerable (I do it often), and I would want this
|
No description provided.