-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Check for :meta expressions more thoroughly, and improve indexing performance #11617
Conversation
This fixes the primary problem in #11595, but is not enough on its own to recapture full performance. Interestingly, this does not appear to cause a measurable slowing of the compilation of base.
This address most of the remaining problem in #11595, but it's still about three-fold short of the performance we had before getindex(::SubArray, ...) checked bounds.
Awesome, thank you @timholy! And thank you to @tkelman and @yuyichao for digging into this with me over the weekend. Theoretically, we're not doing more work than we were before (we still were checking bounds upon accessing the parent array), but there's a lot more indirection and we're definitely making the compiler work harder. I'll try to figure out if it's possible to regain some ground here. Interesting (and wonderful) that this hasn't run into the win32 bug. I just pushed a branch to run on Appveyor to test this branch + the factor of 1000 inline_worthy patch. Even if that fails, we'll have a nice lead on a workaround for the bug without wrecking performance: some function may have to marked |
Success! The only question I have about this implementation is if we really should look anywhere within a function for a meta annotation. When I sat down to do this this morning (before seeing your solution), I just made diff --git a/base/expr.jl b/base/expr.jl
index 49850aa..a8ebade 100644
--- a/base/expr.jl
+++ b/base/expr.jl
@@ -139,8 +139,13 @@ function pushmeta!(ex::Expr, sym::Symbol, args::Any...)
end
function popmeta!(body::Expr, sym::Symbol)
- if isa(body.args[1],Expr) && (body.args[1]::Expr).head === :meta
- metaargs = (body.args[1]::Expr).args
+ # Skip unrelated top-of-function annotations
+ i = 1;
+ while i < length(body.args) && isa(body.args[i],NewvarNode)
+ i+=1
+ end
+ if isa(body.args[i],Expr) && (body.args[i]::Expr).head === :meta
+ metaargs = (body.args[i]::Expr).args
for i = 1:length(metaargs)
if (isa(metaargs[i], Symbol) && metaargs[i] == sym) ||
(isa(metaargs[i], Expr) && metaargs[i].head == sym) My concern here is that we could start using |
For building julia, I got this:
Since I couldn't measure a performance hit, it seemed best to just check the entire expression (recursively, no less). |
Regarding local annotation, I think we'd certainly need a different symbol, e.g., |
Ah, yes, of course. Makes sense. LGTM! |
Check for :meta expressions more thoroughly, and improve indexing performance
Thanks for reviewing. Obviously the |
I guess if we start inserting metadata throughout a function, the biggest concern is that we currently assume that there is at most one |
This addresses #11595, and fixes most of our current problems with indexing performance. Sadly, it still doesn't recover the full performance compared to #5117 (comment). With this PR (running on a different machine, but the times relative to the first should be pretty comparable):
which is a big improvement over the nearly thousand-fold penalty observed in #5117 (comment).
If we want SubArrays to have indexing performance nearly equivalent to Arrays, we probably have to go back to not doing bounds checking 😦.