[ 
https://issues.apache.org/jira/browse/LUCENE-7882?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17197533#comment-17197533
 ] 

Uwe Schindler commented on LUCENE-7882:
---------------------------------------

Hi [~zhai7631],

bq. Thank you for making this fantastic PR!

Thanks! :-)

bq. We've tested this PR by compiling with JDK11 and running with JDK15 
(because of some reason it's not easy to compile our service with JDK15 
directly).

That's perfectly fine. There's no reason to complie anything with JDK 15 
(neither Lucene nor your code), because the defineHiddenClass() is used 
dynamically using MethodHandles if the expressions compiler detects this API to 
be available. So it's perfectly valid to create and compile with JDK 11, as 
long as you benchmark with 15.

bq. But because of the reason I mentioned above, it seems that we don't have 
enough expressions compilation now to observe the difference with or without 
the PR.

That's fine. I was hoping that maybe you or [~mikemccand] have some isolated 
benchmark that creates many expressions with hundreds of threads in parallel :-)

I made this PR more for educational purposes (I just wanted to try out the new 
API and figure out if it helps us). [~rcmuir] also wanted to do some testing 
with the old code he used back in 2013 when we checked the "separate 
classloader per expression" code (which is also mentioned in the JEP about 
defineHiddenClass).

I have not yet committed that PR because of the small problem: the stack frame 
of the expression gets lost, as it's hidden by the JVM. In Robert's and my 
opinion, it's not so important to have the stackframe of 
CompiledExpression#evaluate() as long as users don't produce stack overflows or 
anything like that in their expression. If all functions referred to in the 
expression don't throw any exception, the stack frage is really not needed.

The only open question is: if an expression really fails, we no longer have the 
expression source code in the stack trace, too.

> Maybe expression compiler should cache recently compiled expressions?
> ---------------------------------------------------------------------
>
>                 Key: LUCENE-7882
>                 URL: https://issues.apache.org/jira/browse/LUCENE-7882
>             Project: Lucene - Core
>          Issue Type: Improvement
>          Components: modules/expressions
>            Reporter: Michael McCandless
>            Assignee: Uwe Schindler
>            Priority: Major
>         Attachments: demo.patch
>
>          Time Spent: 1.5h
>  Remaining Estimate: 0h
>
> I've been running search performance tests using a simple expression 
> ({{_score + ln(1000+unit_sales)}}) for sorting and hit this odd bottleneck:
> {noformat}
> "pool-1-thread-30" #70 prio=5 os_prio=0 tid=0x00007eea7000a000 nid=0x1ea8a 
> waiting for monitor entry [0x00007eea867dd000]
>    java.lang.Thread.State: BLOCKED (on object monitor)
>       at 
> org.apache.lucene.expressions.js.JavascriptCompiler$CompiledExpression.evaluate(_score
>  + ln(1000+unit_sales))
>       at 
> org.apache.lucene.expressions.ExpressionFunctionValues.doubleValue(ExpressionFunctionValues.java:49)
>       at 
> com.amazon.lucene.OrderedVELeafCollector.collectInternal(OrderedVELeafCollector.java:123)
>       at 
> com.amazon.lucene.OrderedVELeafCollector.collect(OrderedVELeafCollector.java:108)
>       at 
> org.apache.lucene.search.MultiCollectorManager$Collectors$LeafCollectors.collect(MultiCollectorManager.java:102)
>       at 
> org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll(Weight.java:241)
>       at 
> org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:184)
>       at org.apache.lucene.search.BulkScorer.score(BulkScorer.java:39)
>       at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:658)
>       at org.apache.lucene.search.IndexSearcher$5.call(IndexSearcher.java:600)
>       at org.apache.lucene.search.IndexSearcher$5.call(IndexSearcher.java:597)
>       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
>       at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
>       at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>       at java.lang.Thread.run(Thread.java:745)
> {noformat}
> I couldn't see any {{synchronized}} in the sources here, so I'm not sure 
> which object monitor it's blocked on.
> I was accidentally compiling a new expression for every query, and that 
> bottleneck would cause overall QPS to slow down drastically (~4X slower after 
> ~1 hour of redline tests), as if the JVM is getting slower and slower to 
> evaluate each expression the more expressions I had compiled.
> I tested JDK 9-ea and it also kept slowing down over time as the performance 
> test ran.
> Maybe we should put a small cache in front of the expressions compiler to 
> make it less trappy?  Or maybe we can get to the root cause of why the JVM 
> slows down more and more, the more expressions you compile?
> I won't have time to work on this in the near future so if anyone else feels 
> the itch, please scratch it!



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org
For additional commands, e-mail: issues-h...@lucene.apache.org

Reply via email to