package net.cis.common.script.test;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.jruby.RubyInstanceConfig.CompileMode;
import org.jruby.embed.EmbedEvalUnit;
import org.jruby.embed.ScriptingContainer;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.python.core.PyCode;
import org.python.util.PythonInterpreter;
import se.krka.kahlua.luaj.compiler.LuaCompiler;
import se.krka.kahlua.stdlib.OsLib;
import se.krka.kahlua.test.UserdataArray;
import se.krka.kahlua.vm.LuaClosure;
import se.krka.kahlua.vm.LuaState;
public class ScriptPerformance
{
public static void main(String[] args)
{
System.out.println("Running in: " + new File(".").getAbsolutePath());
System.out.println("Available ScriptEngines:");
javax.script.ScriptEngineManager sem = new ScriptEngineManager();
for (ScriptEngineFactory sef : sem.getEngineFactories())
{
System.out.println(sef.getEngineName() + " - " + sef.getLanguageName());
for (String s : sef.getNames())
System.out.println(" " + s);
}
//runTests(10, 100, false, 1000000);
//runTests(10, 100000, false, 100);
runTestsTimed(10, false, 60000, 1000000);
runTestsTimed(10, false, 60000, 100);
}
public static void runTestsTimed(int warmupRounds, boolean testReallySlowShit, int timeInMilliseconds, int num)
{
System.out.println("Scripts running with n = " + num + " Warmup:"+warmupRounds + " Run time:"+timeInMilliseconds+"ms @Java " + System.getProperty("java.version") + " x" + System.getProperty("sun.arch.data.model"));
Benchmarker b = getBenchmarker(testReallySlowShit, num);
b.runTestsTimed(warmupRounds, timeInMilliseconds);
}
public static void runTests(int warmupRounds, int t, boolean testReallySlowShit, int num)
{
System.out.println("Scripts running with n = " + num + " Warmup:"+warmupRounds + " Timed:"+t + " @Java " + System.getProperty("java.version") + " x" + System.getProperty("sun.arch.data.model"));
Benchmarker b = getBenchmarker(testReallySlowShit, num);
b.runTests(warmupRounds,t);
}
public static Benchmarker getBenchmarker(boolean testReallySlowShit, int num)
{
Benchmarker b = new Benchmarker();
testJava(b, num);
if(testReallySlowShit)
{
testJavascript(b, num);
testJavascriptCompiled(b, num);
}
testJavascriptRhinoDirect(b, num);
testJavascriptRhinoDirectCompiledOnce(b, 0, num);
testJavascriptRhinoDirectCompiledOnce(b, 1, num);
testJavascriptRhinoDirectCompiledOnce(b, 2, num);
testJavascriptRhinoDirectCompiledOnce(b, 9, num);
testJRuby(b, "resource/test/primes.rb", num);
testJRubyCompiled(b, "resource/test/primes.rb", num);
testJRubyDirect(b, "resource/test/primes.rb", num);
testJRubyDirectCompiled(b, "resource/test/primes.rb", num);
testJRuby(b, "resource/test/primes2.rb", num);
testJRubyCompiled(b, "resource/test/primes2.rb", num);
testJRubyDirect(b, "resource/test/primes2.rb", num);
testJRubyDirectCompiled(b, "resource/test/primes2.rb", num);
testJython(b, num);
testJythonCompiled(b, num);
testJythonDirect(b, num);
testJythonDirectCompiled(b, num);
testLuaJ(b, num);
testLuaJCompiled(b, num);
if(testReallySlowShit)
testKahluaDirectCompiled(b, num);
testGroovy(b, num);
testGroovyCompiled(b, num);
testGroovyDirectShell(b, num);
testGroovyDirectShellCompiled(b, num);
//LuaJava not compatible with x64, recompile not possible
return b;
}
private static void testGroovyDirectShellCompiled(Benchmarker b, final long num)
{
b.addTest("GroovyDirectShellCompiled", new IBenchmarkable()
{
Binding binding;
GroovyShell groovyShell;
String groovy;
groovy.lang.Script s;
@Override
public void shutdown()
{
binding = null;
groovyShell = null;
groovy = null;
s = null;
}
@Override
public long run()
{
s.run();
return (Integer)binding.getVariable("numPrimes");
}
@Override
public void init()
{
groovy = "def num="+num+"\r\n" + readFileAsString("resource/test/primes.groovy");
binding = new Binding();
groovyShell = new GroovyShell(binding);
s = groovyShell.parse(groovy);
}
});
}
private static void testGroovyDirectShell(Benchmarker b, final long num)
{
b.addTest("GroovyDirectShell", new IBenchmarkable()
{
Binding binding;
GroovyShell groovyShell;
String groovy;
@Override
public void shutdown()
{
binding = null;
groovyShell = null;
groovy = null;
}
@Override
public long run()
{
groovyShell.evaluate(groovy);
return (Integer)binding.getVariable("numPrimes");
}
@Override
public void init()
{
groovy = "def num="+num+"\r\n" +readFileAsString("resource/test/primes.groovy");
binding = new Binding();
groovyShell = new GroovyShell(binding);
}
});
}
private static void testGroovyCompiled(Benchmarker b, final long num)
{
b.addTest("Groovy precompiled", new IBenchmarkable()
{
ScriptEngineManager factory = null;
ScriptEngine engine;
CompiledScript cs = null;
String js;
Compilable compiler = null;
Bindings bindings;
@Override
public void shutdown()
{
cs = null;
js = null;
engine = null;
compiler = null;
factory = null;
bindings = null;
}
@Override
public long run()
{
try
{
cs.eval(bindings);
return ((Integer)bindings.get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("groovy");
js = "def num="+num+"\r\n" +readFileAsString("resource/test/primes.groovy");
compiler = (Compilable)engine;
engine.put("num", num);
bindings = engine.createBindings();
bindings.put("num", num);
try
{
cs = compiler.compile(js);
}
catch (ScriptException e)
{
e.printStackTrace();
}
}
});
}
private static void testGroovy(Benchmarker b, final long num)
{
b.addTest("Groovy uncompiled", new IBenchmarkable()
{
String js;
ScriptEngine engine;
ScriptEngineManager factory = null;
Bindings bindings;
@Override
public void shutdown()
{
js = null;
engine = null;
factory = null;
bindings = null;
}
@Override
public long run()
{
try
{
engine.eval(js, bindings);
return ((Integer)bindings.get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("groovy");
bindings = engine.createBindings();
bindings.put("num", num);
js = "def num="+num+"\r\n" +readFileAsString("resource/test/primes.groovy");
}
});
}
private static void testKahluaDirectCompiled(Benchmarker b, final long num)
{
b.addTest("KahluaDirectCompiled", new IBenchmarkable()
{
LuaState state;
LuaClosure closure;
String lua;
@Override
public void shutdown()
{
state = null;
closure = null;
lua = null;
}
@Override
public long run()
{
state.call(closure, null);
return 0;
}
@Override
public void init()
{
state = new LuaState(System.out);
UserdataArray.register(state);
OsLib.register(state);
LuaCompiler.register(state);
lua = readFileAsString("resource/test/primes.lua");
try
{
closure = LuaCompiler.loadstring(lua, "primes.lua", state.getEnvironment());
}
catch (IOException e)
{
e.printStackTrace();
}
}
});
}
private static void testLuaJCompiled(Benchmarker b, final long num)
{
b.addTest("LuaJ precompiled", new IBenchmarkable()
{
ScriptEngineManager factory = null;
ScriptEngine engine;
CompiledScript cs = null;
String js;
Compilable compiler = null;
@Override
public void shutdown()
{
cs = null;
js = null;
engine = null;
compiler = null;
factory = null;
}
@Override
public long run()
{
try
{
cs.eval();
return ((Integer)cs.getEngine().get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("luaj");
js = readFileAsString("resource/test/primes.lua");
compiler = (Compilable)engine;
engine.put("num", num);
try
{
cs = compiler.compile(js);
}
catch (ScriptException e)
{
e.printStackTrace();
}
}
});
}
private static void testLuaJ(Benchmarker b, final long num)
{
b.addTest("LuaJ uncompiled", new IBenchmarkable()
{
String js;
ScriptEngine engine;
ScriptEngineManager factory = null;
@Override
public void shutdown()
{
js = null;
engine = null;
factory = null;
}
@Override
public long run()
{
try
{
engine.eval(js);
return ((Integer)engine.get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("luaj");
engine.put("num", num);
js = readFileAsString("resource/test/primes.lua");
}
});
}
private static void testJythonDirectCompiled(Benchmarker b, final long num)
{
b.addTest("JythonDirectCompiled", new IBenchmarkable()
{
PythonInterpreter pi;
String py;
PyCode pycode;
@Override
public void shutdown()
{
pi = null;
py = null;
pycode = null;
}
@Override
public long run()
{
pi.exec(pycode);
return pi.get("numPrimes").asLong();
}
@Override
public void init()
{
pi = new PythonInterpreter();
pi.set("numPrimes", 0L);
pi.set("num", num);
py = readFileAsString("resource/test/primes.py");
pycode = pi.compile(py);
}
});
}
private static void testJythonDirect(Benchmarker b, final long num)
{
b.addTest("JythonDirect", new IBenchmarkable()
{
PythonInterpreter pi;
String py;
@Override
public void shutdown()
{
pi = null;
py = null;
}
@Override
public long run()
{
pi.exec(py);
return pi.get("numPrimes").asLong();
}
@Override
public void init()
{
pi = new PythonInterpreter();
pi.set("numPrimes", 0L);
pi.set("num", num);
py = readFileAsString("resource/test/primes.py");
}
});
}
private static void testJythonCompiled(Benchmarker b, final long num)
{
b.addTest("Jython precompiled", new IBenchmarkable()
{
ScriptEngineManager factory = null;
ScriptEngine engine;
CompiledScript cs = null;
String js;
Compilable compiler = null;
@Override
public void shutdown()
{
cs = null;
js = null;
engine = null;
compiler = null;
factory = null;
}
@Override
public long run()
{
try
{
cs.eval();
return ((Integer)cs.getEngine().get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("jython");
js = readFileAsString("resource/test/primes.py");
compiler = (Compilable)engine;
engine.put("num", num);
try
{
cs = compiler.compile(js);
}
catch (ScriptException e)
{
e.printStackTrace();
}
}
});
}
private static void testJython(Benchmarker b, final long num)
{
b.addTest("Jython uncompiled", new IBenchmarkable()
{
String js;
ScriptEngine engine;
ScriptEngineManager factory = null;
@Override
public void shutdown()
{
js = null;
engine = null;
factory = null;
}
@Override
public long run()
{
try
{
engine.eval(js);
return ((Integer)engine.get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("jython");
engine.put("num", num);
js = readFileAsString("resource/test/primes.py");
}
});
}
private static void testJRubyDirectCompiled(Benchmarker b, final String file, final long num)
{
b.addTest("JRubyDirectCompiled ("+file+")", new IBenchmarkable()
{
ScriptingContainer container;
String ruby;
EmbedEvalUnit s;
@Override
public void shutdown()
{
container.terminate();
container = null;
ruby = null;
s = null;
}
@Override
public long run()
{
s.run();
return ((Long)container.get("numPrimes")).longValue();
}
@Override
public void init()
{
container = new ScriptingContainer();
container.setCompileMode(CompileMode.FORCE);
container.put("$numPrimes", 0L);
container.setAttribute("$num", num);
ruby = readFileAsString(file);
s = container.parse(ruby);
}
});
}
private static void testJRubyDirect(Benchmarker b, final String file, final long num)
{
b.addTest("JRubyDirect ("+file+")", new IBenchmarkable()
{
ScriptingContainer container;
String ruby;
@Override
public void shutdown()
{
container.terminate();
container = null;
ruby = null;
}
@Override
public long run()
{
container.runScriptlet(ruby);
return ((Long)container.get("numPrimes")).longValue();
}
@Override
public void init()
{
container = new ScriptingContainer();
container.setCompileMode(CompileMode.OFF);
container.setAttribute("$numPrimes", 0L);
container.setAttribute("$num", num);
ruby = readFileAsString(file);
}
});
}
private static void testJRubyCompiled(Benchmarker b, final String file, final long num)
{
b.addTest("JRuby precompiled ("+file+")", new IBenchmarkable()
{
ScriptEngineManager factory = null;
ScriptEngine engine;
CompiledScript cs = null;
String js;
Compilable compiler = null;
@Override
public void shutdown()
{
cs = null;
js = null;
engine = null;
compiler = null;
factory = null;
}
@Override
public long run()
{
try
{
cs.eval();
return ((Long)cs.getEngine().get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("jruby");
js = readFileAsString(file);
engine.put("$numPrimes", 0L);
compiler = (Compilable)engine;
engine.put("num", num);
try
{
cs = compiler.compile(js);
}
catch (ScriptException e)
{
e.printStackTrace();
}
}
});
}
private static void testJRuby(Benchmarker b, final String file, final long num)
{
b.addTest("JRuby uncompiled ("+file+")", new IBenchmarkable()
{
String js;
ScriptEngine engine;
ScriptEngineManager factory = null;
@Override
public void shutdown()
{
js = null;
engine = null;
factory = null;
}
@Override
public long run()
{
try
{
engine.put("$numPrimes", 0L);
engine.eval(js);
return ((Long)engine.get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("jruby");
engine.put("num", num);
js = readFileAsString(file);
}
});
}
private static void testJavascriptRhinoDirectCompiledOnce(Benchmarker b, final int optimisationLevel, final long num)
{
b.addTest("RhinoJSCompiled L" + optimisationLevel, new IBenchmarkable()
{
Context ctx;
Script s;
Scriptable scope;
String js;
@Override
public void shutdown()
{
ctx = null;
s = null;
scope = null;
Context.exit();
js = null;
}
@Override
public long run()
{
s.exec(ctx, scope);
return ((Double)scope.get("numPrimes", scope)).longValue();
}
@Override
public void init()
{
js = readFileAsString("resource/test/primes.js");
ctx = Context.enter();
ctx.setOptimizationLevel(optimisationLevel);
s = ctx.compileString(js, "primes.js", 1, null);
scope = ctx.initStandardObjects();
scope.put("num", scope, num);
}
});
}
private static void testJavascriptRhinoDirect(Benchmarker b, final long num)
{
final String js = readFileAsString("resource/test/primes.js");
b.addTest("RhinoJS", new IBenchmarkable()
{
@Override
public void shutdown()
{
Context.exit();
}
@Override
public long run()
{
try
{
Context ctx = Context.enter();
Scriptable scope = ctx.initStandardObjects();
scope.put("num", scope, num);
ctx.evaluateString(scope, js, "primes.js", 1, null);
return ((Double)scope.get("numPrimes", scope)).longValue();
}
finally
{
}
}
@Override
public void init()
{
}
});
}
private static void testJavascriptCompiled(Benchmarker b, final long num)
{
b.addTest("Javascript precompiled", new IBenchmarkable()
{
ScriptEngineManager factory = null;
ScriptEngine engine;
CompiledScript cs = null;
String js;
Compilable compiler = null;
@Override
public void shutdown()
{
cs = null;
js = null;
engine = null;
compiler = null;
factory = null;
}
@Override
public long run()
{
try
{
cs.eval();
return ((Double)cs.getEngine().get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("JavaScript");
js = readFileAsString("resource/test/primes.js");
compiler = (Compilable)engine;
engine.put("num", num);
try
{
cs = compiler.compile(js);
}
catch (ScriptException e)
{
e.printStackTrace();
}
}
});
}
private static void testJavascript(Benchmarker b, final long num)
{
b.addTest("Javascript uncompiled", new IBenchmarkable()
{
String js;
ScriptEngine engine;
ScriptEngineManager factory = null;
@Override
public void shutdown()
{
js = null;
engine = null;
factory = null;
}
@Override
public long run()
{
try
{
engine.eval(js);
return ((Double)engine.get("numPrimes")).longValue();
}
catch (ScriptException e)
{
e.printStackTrace();
}
return 0;
}
@Override
public void init()
{
factory = new ScriptEngineManager();
engine = factory.getEngineByName("JavaScript");
engine.put("num", num);
js = readFileAsString("resource/test/primes.js");
}
});
}
private static void testJava(Benchmarker b, final long num)
{
b.addTest("Java", new IBenchmarkable()
{
@Override
public void shutdown()
{
}
@Override
public long run()
{
ArrayList<Integer> primes = get_primes7(num);
return primes.size();
}
@Override
public void init()
{
}
});
}
public static ArrayList<Integer> get_primes7(long n)
{
ArrayList<Integer> res = new ArrayList<Integer>();
if (n < 2) return res;
if (n == 2)
{
res.add(2);
return res;
}
ArrayList<Integer> s = new ArrayList<Integer>();
for (int i = 3; i < n + 1; i += 2)
{
s.add(i);
}
int mroot = (int) Math.sqrt(n);
int half = s.size();
int i = 0;
int m = 3;
while (m <= mroot)
{
if (s.get(i) != 0)
{
int j = (int) ((m * m - 3) / 2);
//s.set(j, 0);
while (j < half)
{
s.set(j, 0);
j += m;
}
}
i = i + 1;
m = 2 * i + 3;
}
res.add(2);
for (int it = 0; it < s.size(); ++it)
{
if (s.get(it) != 0)
{
res.add(s.get(it));
}
}
return res;
}
private static String readFileAsString(String filePath)
{
try
{
byte[] buffer = new byte[(int) new File(filePath).length()];
FileInputStream f = new FileInputStream(filePath);
f.read(buffer);
f.close();
return new String(buffer);
}
catch (Exception e)
{
e.printStackTrace();
return "";
}
}
}