-
Notifications
You must be signed in to change notification settings - Fork 181
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
Binding is slow #788
Comments
You are right that So, you can rewrite your
There is a similar problem with the repeated invocation of
You may wonder why I don't suggest to use
That's because I found that we do not specialize well the delete performed on a global object. I have fixed this bug already, but I don't expect you to use the latest development build. So, the In fact, it may be redundant to do anything in Finally, I noticed that your example runs in interpreter mode only (without runtime compilation). I hope that this is just to keep the example simple. If you care about performance then you should run with runtime compilation, of course. When I applied the mentioned suggestions then the execution time of your example decreased from ~30s to ~0.35s on my machine. |
Thank you! Using a script to bind the values has improved performance dramatically. I've modified my code (and committed to the repo) to time 300,000 evaluations (originally 30,000) and to use runtime compilation and execution after warmup is - for me - ~1.5 seconds with GraalJS vs 2 seconds with Rhino. The reason I was using interpreter only mode is that I'm only able to execute with compilation enabled when running from my IDE. With an uber jar I get an exception saying:
|
@iamstolis Thanks for your advice on all of this, it took me longer to circle back to it than I had hoped it would. I ended up dealing with "unbinding" by evaluating:
From your comment, it seems that using delete may be the way to go in the future; however, using delete currently seems to have no effect (the variable remains in the bindings map with its value unchanged). (Incidentally, the issue with running in non-interpreted mode was resolved by moving to the 21.0.2 VM) |
(NOTE: A repository with code that demonstrates the issue is here: js-engine-performance)
I'm evaluating the feasibility of moving from using Rhino to GraalJS. The scenario is user defined expressions are being evaluated in a Context that has a number of variables bound to it, each expression may or may not refer to some of the bound variables. A Context may be short-lived, so it's important that creating them and binding variables is speedy - unfortunately both creating a polyglot context and binding variables in it is significantly slower than using Rhino.
I believe the issue with slow Context creation can be alleviated by using a pool of Contexts rather then creating a new one each time. The code linked above is somewhat simpler, as it's only running single-threaded and so can simply clear out the bindings and reuse a single Context.
The bindings problem is a thornier issue. The linked code times how long it takes to do 30,000: context creation; variable bind (100 variables); expression evaluation; context close.
On my machine this takes Rhino approximately 0.2 seconds, but GraalJS takes around 20 seconds.
In the case where an expression on references a small number of variables, performance can be improved by pre-parsing the expression to be evaluated and only binding referenced variables (the example code does very basic parsing and assumes each variable is surrounded by white space). Rather than having to parse expressions before evaluation, is there a way in which a variable can be bound at the point the engine tries to access a value and finds it's not bound? Better still, is there any way to make binding faster?
I'm running using:
java version "21.0.1" 2023-10-17
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.1+12.1 (build 21.0.1+12-jvmci-23.1-b19, mixed mode, sharing)
With version 23.1.1 of the Graal libraries.
Full code is in the linke repo, but as an outline:
I have an Evaluator interface, the GraalJs implementation is created using the following factory:
The sourceFatory is one of these (performance of both is similar):
With a "binder" to bind values defined in a variables map:
With a single evaluation being performed thus:
The text was updated successfully, but these errors were encountered: