Android: low performance in LiquidCore/nodejs compared to V8-only mode (factor >1000)
Znerole opened this issue · comments
I had some debate on the performance of different ways of iterating over an array and decided to benchmark this. I also tried LiquidCore and found it to be several orders of magnitude slower than either a different node implementation for Android (https://github.com/JaneaSystems/nodejs-mobile) or Chrome on the same device. The release build of LiquidCore build is a bit faster than debug (factor 10, maybe), but still very slow.
In an attempt to isolate the issue, I tried the same benchmark with the V8-only mode using just the liquidcore-V8 module and it turns out to be much much faster, the main bottleneck now being calls to performance.now()
which I substituted with a Java implementation. Removing this brings the performance to the same level as nodejs-mobile or Chrome.
So, apparently it had something to do with the way LiquidCore sets up nodejs.
I ran some profiling and found that 88% of the CPU time is spent by a call from PropertyCallbackArguments::BasicCallNamedGetterCallback
(which is a v8 function) to OpaqueJSClass::NamedPropertyGetter
(which is part of liquidcore-v8).
Digging around, it appears to me that all property accesses are routed through the OpaqueJSClass
, causing a severe performance bottleneck.
Unfortunately I'm out of my wits here and I find myself unable to work around or even fix this issue. Is OpaqueJSClass
simply not optimized enough or is it too involved?
The benchmark is available on jsfiddle: https://jsfiddle.net/m0kpy1ju/
The javascript code runs either in the browser or standalone in nodejs (or LiquidCore).
I used the following code to setup my liquidcore-V8 instance:
JSContext context = new JSContext();
{
// console somehow doesn't work right out of the box
JSObject console = new JSObject(context);
console.property("log", new JSFunction(context, "log") {
public void log(String s) {
Log.i("V8", s);
}
});
console.property("group", new JSFunction(context, "group") {
public void group(String s) {
Log.i("V8", s);
}
});
console.property("groupEnd", new JSFunction(context, "groupEnd") {
public void groupEnd() {
}
});
context.property("console", console);
}
{
JSObject performance = new JSObject(context);
performance.property("now", new JSFunction(context, "now") {
public Long now() {
return System.currentTimeMillis();
}
});
context.property("performance", performance);
}
I tested LiquidCore 0.7.10 and also 0.6.1, both show the low performance.
Duplicate of #202