Script Compilation with Nashorn

Many developers know that a new JavaScript engine called Nashorn was introduced in Java 8 as a replacement for the aging Rhino engine.  Recently, I (finally) had the opportunity to make use of the capability.

The project is a custom NiFi processor that utilizes a custom configuration-based data transformation engine.  The configurations make heavy use of JavaScript-based mappings to move and munge fields from a source schema into a target schema.  Our initial testing revealed rather lackluster performance.  JProfiler indicated that the hotspot was the script engine’s eval() method, which really wasn’t that helpful since I already knew that script execution was going to be the long pole in the tent.

It turned out that I had missed an opportunity during the initial implementation.  The Nashorn script engine implements Compilable, a functional interface that allows you to compile your script.

@Test
public void testWithCompilation() throws Exception {
    ScriptEngine engine = mgr.getEngineByName("nashorn");
    CompiledScript compiled = ((Compilable) engine).compile("value = 'junit';");
    for (int i = 0; i < 10000; i++) {
        Bindings bindings = engine.createBindings();
        compiled.eval(bindings);
        Object result = bindings.get("value");
        Assert.assertEquals(result, "junit");
    }
}

@Test
public void testWithoutCompilation() throws Exception {
    for (int i = 0; i < 10000; i++) {
        ScriptEngine engine = mgr.getEngineByName("nashorn");
        engine.eval("value = 'junit';");
        Object result = engine.get("value");
        Assert.assertEquals(result, "junit");
    }
}

junit

As you can see, the difference is substantial across a test of 10,000 invocations.  A batch size of a few million records is pretty ordinary for the system that uses this component, so this represents a huge time savings.

I should also mention that the script engine is thread safe.  For concurrent use, each thread simply needs to obtain a fresh bindings instance from the engine as shown in the code above.

I get the impression that Nashorn may be an underutilized feature in the JDK.  However, script-based extensibility in an application can be quite valuable in certain scenarios.  Nashorn is worth keeping in mind for your future projects.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s