Skip to content
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

Android: low performance in LiquidCore/nodejs compared to V8-only mode (factor >1000) #202

Open
Znerole opened this issue Feb 2, 2021 · 1 comment

Comments

@Znerole
Copy link

Znerole commented Feb 2, 2021

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).

This is the flame graph:
image

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.

@Znerole Znerole changed the title Android: low performance in LiquidCore compared to V8-only mode (factor >1000) Android: low performance in LiquidCore/nodejs compared to V8-only mode (factor >1000) Feb 2, 2021
@unreal-person-666
Copy link

Duplicate of #202

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants