Thursday, April 19, 2012

Groovy Eval slow performance

Groovy Eval is nice feature, unfortunately it does not have great performance. Recently, I had to calculate values on a bunch of objects and got quite dramatic performance issue. After quick investigation, I pinpointed problem to be with Eval, which can be summarized to:


def t = System.currentTimeMillis()
1000.times {
  Eval.x(44, 'x>3')
}
println (System.currentTimeMillis() - t)
7281
I tried to check if there is other solution that could do the same and I found that there is similar native Java function. In similar test I got:


import javax.script.ScriptEngine
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings

def t = System.currentTimeMillis()
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
1000.times {
  engine.eval('x>3', new SimpleBindings([x:44]))
}
println (System.currentTimeMillis() - t)
250

Obviously, it will not be absolutely the same in general and I assume Eval provides much more (and looks less ugly), but ScriptEngine is good enough for my case and it performs almost 30 times faster.

2 comments:

  1. Hi Artjomenko,

    I agree, Eval is definitely slow. After some reseach (http://tinyurl.com/7nwjbl5) I will use MVEL in my framework.

    Nice post.

    ReplyDelete
  2. Nice post!,

    bit late but (in groovy 2.1.3, at least,) performance is improved a lot if you use groovy through the script engine interface:

    groovyEngine = new ScriptEngineManager().getEngineByName("groovy");

    My own anecdotal evidence, with no accounting for jvm warm up:

    groovy: Eval.me took:~8.0s
    groovy: Script Engine took:~0.2s
    js : Script Engine took:~0.1s

    ReplyDelete