Measuring Rhino performance using Android instrumentation test (AndroidJUnitRunner)

47 views
Skip to first unread message

Denis Voloshin

unread,
Jul 7, 2017, 4:50:45 AM7/7/17
to mozilla-rhino

I'm having low Rhino performance issues while executing Rhino code on Android real device.

The Rhino context is initiated with a string which represents big JSON object, the total string size is around 120K, to test code performance we wrote a few instrumental tests to check the code performance, however, we are getting not clear result the same code, with the same parameters shows absolutely different results between tests and sample app.

The test performance 10 times faster than the same code is executed as an instrumental test then on it's running as part of the sample app on the same device (G5). BTW the android emulator also shows good performance result.

the code is pretty simple


private void init(String jFfunctionsDeclaration) throws ScriptInitException {
        StringBuilder ruleEngineContextBuffer = new StringBuilder();


        //create a JSON object in the string representation, later Rhino context will be initialized with this string  
        for (Map.Entry<String, String> e : scriptObjects.entrySet()) {
            String key = e.getKey();
            String value = e.getValue();
            ruleEngineContextBuffer.append("\nvar ");
            ruleEngineContextBuffer.append(key);
            ruleEngineContextBuffer.append(" = "); // append(" = JSON.parse(");
            ruleEngineContextBuffer.append(value);
        }

        // create and enter safe execution context to prevent endless loop or deadlock in JS
        // because Rhino input it provided from outside
        SafeContextFactory safeContextFactory = new SafeContextFactory();
        rhino = safeContextFactory.makeContext().enter();

        try {
            // the fisrt init step, init Rhino cotext with JS utils methods
            // functions input is the list of JS functions
            sharedScope = rhino.initStandardObjects();
            rhino.evaluateString(sharedScope, functions, "<init1>", 1, null);
            String str = ruleEngineContextBuffer.toString();

            long startContextInit = System.currentTimeMillis();
            rhino.evaluateString(sharedScope, str, "<init2>", 1, null);
            long totalContextInit = System.currentTimeMillis() - startContextInit;
            Log.d(TAG, "Rhino context init duration = " + totalContextInit);
        } catch (Throwable e) {
            throw new ScriptInitException("Javascript shared scope initialization error: " + e.getMessage());
        }
    }

could someone explain me this mystery, thanks? The problem that all my considerations whether to integrate the Rhino lib into the production app were based on these results which in fact are wrong.


Gregory Brail

unread,
Jul 7, 2017, 12:39:59 PM7/7/17
to mozill...@googlegroups.com
It's hard to tell what you are trying to do or what the difference might be between your test and the real code.

One thing that I will say is that all the setup stuff involved with Rhino is expensive. "initStandardObjects()" in particular does a lot. If you're trying to run JavaScript code over and over on Android, then if you can possibly cache some of that you will get much better performance.

Similarly, "evaluateString," at least on standard Java platforms, first compiles the JavaScript to bytecode and then executes it. If you can compile it once and then execute it multiple times you will see a vast difference. Unfortunately I'm not familiar enough with the way that Rhino is used on Android to know whether there should be a difference.


--
You received this message because you are subscribed to the Google Groups "mozilla-rhino" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mozilla-rhino+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Denis Voloshin

unread,
Jul 7, 2017, 3:31:05 PM7/7/17
to mozilla-rhino
Hi Gregory, thanks for your answer, in my case the evaluateString method is the most expensive because the input is always different, the input is big JSON object in the string representation which should be evaluated and later I use it as an input in my business logic, so it's not possible to optimize it by doing precompilation and reuse it again.  My main question is how come instrumentation test knows to execute such expensive Rhino code so efficiently and why when I run the same code within Android app it's executed differently and what should I do to obtain the performance because the instrumentation test also is executed on the same device. 


thanks
To unsubscribe from this group and stop receiving emails from it, send an email to mozilla-rhin...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages