-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Only use ExprEval in ConstantExpr if its known that it will be safe #15694
Conversation
I had a question regarding this: The original PR aimed to optimize the case with Expr creating a new ExprEval for every constant expression, which we can do away with. WDYT about creating a precached ExprEval (which is thread-safe) for constant expressions, instead of creating a thread-unsafe |
|
I meant the ConstantExprs would hold a thread-safe version of |
sorry accidentally hit comment button while i was typing out previous comment 😅 I think i was more or less agreeing with you that it feels a bit off that the |
The reason I've stuck to this approach beause @gianm have mentioned that this approach might be usefull in the future around at the end of this comment. Making an immutable partial code public ExprEval<T> makeImmutableExprEval(ExprEval e) {
int intVal = e.asInt();
long longVal = e.asLong();
String stringVal = e.asString();
return new ExprEval<T>() {
@Override
public int asInt()
{
return intVal;
}
@Override
public long asLong()
{
return longVal;
}
@Override
public String asString()
{
return asString();
}
//[...]
}
} Another alternate approach could be to change the way caching works in
|
note I was looking a bit into the above alternate approaches:
I think the |
* For top level expressions use {@link Expr#makeSingleThreaded(Expr)} to | ||
* obtain the single-threaded version of the expression tree. | ||
*/ | ||
default Expr singleThreaded() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is a usage mistake waiting to happen. People will call expr.singleThreaded()
and then be surprised that it doesn't actually make a single-threaded expr tree. IMO it's better for this method to apply a visitor that goes and replaces all the ConstantExprs, even though it takes some control away from non-constant Exprs to customize their behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made changes to this and replaced it with a better approach
its kinda the same what we had in the original PR; but the impact of this highly depends on the number of constants at play....and although it has performance benefits - it really just reduces the amount of garbage being created and by that it even reduces the error of the execution times I've done the following runs:
I always wanted to look into what tools are available to compare jmh results - the ui I've found is not really designed to compare 4 results...but I think its usable: |
@kgyrtkirk what is your analysis of the benchmarking results— what are the take-aways, and do they tell us something about what is the best path? |
I've made some minor changes the way this single threaded version is created/supported by exprs. Before replying on perf/etc I wanted to see how a more convoluted case performs: I've added a case statement with a 100 branches.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The general idea LGTM. Had a few comments.
processing/src/main/java/org/apache/druid/math/expr/ConstantExpr.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i still find this change to be sad because its basically a forced function since there is no good reason to be calling eval
without first going through the single threaded stuff, but doing it better would just be too much work that it doesn't feel worth it and hopefully we can just drop all non-vectorized evaluation someday so this can just go away
The doc failure is unrelated, we can merge this |
…pache#15694) * which creates a singleThreaded version of the actual expression (caching ExprEval is allowed) * to make a whole subtree of expressions 'singleThreaded' - uses to create the new expression tree * creates a specialized which does cache the * some annotations were added to make it more likely to notice that there might be something off if a similar change will be made around here for some reason (cherry picked from commit 27d7c30)
…l be safe (#15694) (#16100) * which creates a singleThreaded version of the actual expression (caching ExprEval is allowed) * to make a whole subtree of expressions 'singleThreaded' - uses to create the new expression tree * creates a specialized which does cache the * some annotations were added to make it more likely to notice that there might be something off if a similar change will be made around here for some reason (cherry picked from commit 27d7c30)
As discussed after #15552 was merged (relevant conversation starts from this comment ) there might be a chance that the patch have caused the
ConstantExpr
classes to be unsafe due to the fact thatExprEval
is unsafe as it contains a string-caching logic.To become thread-safe for sure - but still retain the benefits of not producing
ExprEval
objects every time a constant is evaluated; this patch adds:Expr#singleThreaded
which creates a singleThreaded version of the actual expression (caching ExprEval is allowed)Expr#makeSingleThreaded
to make a whole subtree of expressions singleThreadedShuttle
to create the new expression treeConstantExpr#singleThreaded
creates a specializedConstantExpr
which does cache theExprEval
@Immutable
annotations were added to make it more likely to notice that there might be something off if a similar change will be made around here for some reason