-
Notifications
You must be signed in to change notification settings - Fork 35
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
Performance opportunities #206
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
What is your opinion about pushing things to For example,
Is it a slippery slope to start doing this? |
We could temporarily pop them from |
I worry about that slope. Where do we stop? Will packages suddenly fill with |
I do propose special handling of Also, if we start using compiled frames, one thought: I think there are only two classes of slow-to-interpret methods: ones that iterate and ones that recurse. If we can detect those specifically then we might save ourselves compile time. |
Here is a fun one: julia> using JuliaInterpreter, Plots
julia> @time @interpret plot(rand(5))
5.703063 seconds (39.36 M allocations: 2.545 GiB, 6.56% gc time) vs julia> using JuliaInterpreter, CSV, Plots # note the CSV load
julia> @time @interpret plot(rand(5))
16.160595 seconds (51.27 M allocations: 2.868 GiB, 3.46% gc time) |
Is it all method-table searches? (Basically, |
I haven't profiled yet, just observed it. |
I think this is the problem: julia> using BenchmarkTools
julia> c = Some{Any}("foo")
Some("foo")
julia> @code_warntype convert(Some{Any}, c)
Body::Some{Any}
1 ─ %1 = (Base.getfield)(x, :value)::Any
│ %2 = %new(Some{Any}, %1)::Some{Any}
└── return %2
julia> @btime convert(Some{Any}, $c)
4.299 ns (1 allocation: 16 bytes)
Some("foo")
julia> using CSV
julia> @code_warntype convert(Some{Any}, c)
Body::Some{Any}
1 ─ %1 = $(Expr(:static_parameter, 1))::Core.Compiler.Const(Any, false)
│ %2 = (Base.getfield)(x, :value)::Any
│ %3 = (Base.convert)(%1, %2)::Any
│ %4 = (Some{Any})(%3)::Some{Any}
└── return %4
julia> @btime convert(Some{Any}, $c)
923.077 ns (1 allocation: 16 bytes)
Some("foo") |
With JuliaLang/julia#31536 we are at
for the non CSV case and
with CSV. So much better but still signficiantly slower. |
Changing
vs master
We changed this when we found the bug when I executed the same snippet twice and managed to get two of the same frames into the Vector. However, perhaps we can be smarter here than just uses a full blown |
👍 In theory it seems possible to design the logic such that we never put the same frame in twice. In that case we can just use |
In my initial performance work, the big 3 improvements were local method tables (
framecode.methodtables
), reusing framedata (thejunk
mechanism), and getting rid of runtime dispatch internally within the interpreter (by manual union-splitting, aka,if isa(x, ConcreteType)...
).Some possible future improvements:
Core._apply
,Core._apply_latest
, andinvoke
hurt performance. Perhaps some of that might be clawed back by moving more of this work intooptimize!
?ccall
s are slow. I just pushed ateh/compiled_ccall
that contains an old attempt to create one compiled function perccall
. I was most interested in seeing whether it would circumvent MWE of char crash #28 (it didn't seem to), but I don't think I looked at its runtime implications (esp on a ccall-heavy workload). I suspect that branch is pretty close to usable, if anyone wants to pick it up and run with it.iterate
and do something special, a.k.a., (1) determine whetheriterate
could possibly hit a breakpoint or error (if not then you're allowed to play tricks), (2) see if you can determine whether the loop will be long, and if so (3) pass the iterator and frame to a specialrun_loop
function. That would have to compile for each iterator type, so is worth doing only if the loop is long. But you would save the time spent diving in and out ofiterate
, and that could be quite helpful.arrayref
could be improved by separately treating small dimensions (e.g.,if nargs == 1 ... elseif nargs == 2 ... elseif nargs == 3 ... else <varargs version> end
.Obviously spending some time with ProfileView will be useful. I did a ton of that at the beginning and fixed most everything I that I noticed. But I haven't done it in a while and we may have regressed in places as we expanded our functionality.
The text was updated successfully, but these errors were encountered: