-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[jsscripting] Improve performance & reduce memory usage #14113
[jsscripting] Improve performance & reduce memory usage #14113
Conversation
…alJSScriptEngine instances See oracle/graaljs#121 (comment), it is not required to have one engine per GraalJSScriptEngine. This might improve performance a bit on less powerful systems (Raspberry Pi) and decreases heap usage: With 5 GraalJS UI scripts, heap usage is now below 100 MB. Before this change, it was over 100 MB. Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
Will this affect the "closing" of the script engine that we recently introduced? |
I don’t think so.
|
Hopefully this does not bring us into trouble with multi-threaded access, but I'm sure you checked that. |
I don't expect it to do so, since the problem with multi-threaded access is coming from the polyglot I have two script files in the UI: This one here checks whether multi-thread access is properly synchronized inside one var Thread = Java.type('java.lang.Thread');
// Create 100 timers for the same timeout to ensure that timers/scheduled are now threadsafe
for (var i = 0; i < 100; i++) {
function gnr (index) {
return () => {
console.info('setTimeout ' + index + ' completed successfully');
Thread.sleep(500);
};
};
setTimeout(gnr(i), 100);
}
// Ensure that the rule is still running when the timers expire
Thread.sleep(5000); And the second one: var Thread = Java.type('java.lang.Thread');
console.warn('Starting Thread.sleep(60 sec)...')
Thread.sleep(60000);
console.warn('Finished with sleeping.') The result: |
Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
org.graalvm.polyglot.Engine
to reduce memory usage
Just curious, can you share more here? I guess it was not 99,99 MB vs. 100,01 MB? :-) |
I currently don’t have my PC on so I can’t check, but IIRC it was something like 120MB vs 80MB. |
Okay, that seems quite significant! The description of below and above 100 MB just really didn't tell much. 😄 |
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.
LGTM!
i think this is a worth while exercise, I can take a look a little bit on this, but i'm sure you will beat me to a solution :-) |
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.
Thank you!
To improve performance with the library, we would also need to cache it the same way as the globals script. My idea is, to check on creation of the @digitaldan WDYT of that proposal? |
We have a file watcher class to look for changes to the local node_modules dir, would it not be possible to thread safely update the shared |
I‘m not sure if that’s possible, I need to check that in the code . |
So i started thinking about this in earnest, and realized that yeah, doing this might be very tough given how we have a different loading mechanism for loading packages out of |
Yes, we can make it part of the binding configuration, and I agree that this would make it a cleaner solution with less complexity. I will see if I can implement this. |
See #14135 for openhab-js injection caching. |
* [jsscripting] Share org.graalvm.polyglot.Engine across all OpenhabGraalJSScriptEngine instances See oracle/graaljs#121 (comment), it is not required to have one engine per GraalJSScriptEngine. This might improve performance a bit on less powerful systems (Raspberry Pi) and decreases heap usage: With 5 GraalJS UI scripts, heap usage is now below 100 MB. Before this change, it was over 100 MB. * [jsscripting] Extend debug logging * [jsscripting] Cache `@jsscripting-globals.js` across all engines Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
* [jsscripting] Share org.graalvm.polyglot.Engine across all OpenhabGraalJSScriptEngine instances See oracle/graaljs#121 (comment), it is not required to have one engine per GraalJSScriptEngine. This might improve performance a bit on less powerful systems (Raspberry Pi) and decreases heap usage: With 5 GraalJS UI scripts, heap usage is now below 100 MB. Before this change, it was over 100 MB. * [jsscripting] Extend debug logging * [jsscripting] Cache `@jsscripting-globals.js` across all engines Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
* [jsscripting] Share org.graalvm.polyglot.Engine across all OpenhabGraalJSScriptEngine instances See oracle/graaljs#121 (comment), it is not required to have one engine per GraalJSScriptEngine. This might improve performance a bit on less powerful systems (Raspberry Pi) and decreases heap usage: With 5 GraalJS UI scripts, heap usage is now below 100 MB. Before this change, it was over 100 MB. * [jsscripting] Extend debug logging * [jsscripting] Cache `@jsscripting-globals.js` across all engines Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
Description
Improve performance
Performance is improved by caching parts of the global code that is injected into each new script, see e4c9547.
Currently, only the
@jsscripting-globals.js
is cached, but if you disable the injection of globals into UI scripts inside the UI's settings, you can see the effect of this code caching: scripts are extremely fast evaluated, even on my Pi 3 the evaluation time is nearly zero.For some background, see:
I would like to also cache the library code, but I am not sure how to do this while keeping the ability to reload the library during runtime of the addon. Since this will be a larger change, I won’t do this in this PR.
Reduce memory usage
This is mainly done by sharing one
org.graalvm.polyglot.Engine
across allOpenhabGraalJSScriptEngine
s, see a86e32a.Also see oracle/graaljs#121 (comment), it is not required to have one engine per GraalJSScriptEngine.
This results in the following: With 5 GraalJS UI scripts, heap usage is now below 100 MB. Before this change, it was over 100 MB.
Concerns One Can Have
Current changes refers to what changed until commit e4c9547.
@digitaldan This might be interesting for you and I’d like to get your review here.