在開發過程中,經常會需要在程序運行時使用腳本,在java中可以使用諸如Groovy等運行在JVM上的腳本,需要對應添加依賴。也可以直接使用java腳本(使用janino庫來進行編譯,或者使用JavaCompile API ToolProvider 鏈接)。通常我們使用的腳本都是解釋型腳本,其實java本來就自帶了腳本相關的類庫。即 ScriptEngineManager 類,通常我們使用該類來執行javascript腳本,今天就簡單來使用一下。
import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class JavaScriptTest { public static void main(String[] args) throws ScriptException, NoSuchMethodException { long l = System.currentTimeMillis(); for (int i = 0; i < 1000 ; i++) { String script = "function run(arg){if (arg>500){return 0}else{return arg}}"; System.out.println(jsRun("run", script, i)); } System.out.println("耗時:"+String.valueOf(System.currentTimeMillis() - l)); } /** * * @param methodName js腳本方法名 * @param script js 腳本內容 * @param args js方法參數 * @return * @throws ScriptException * @throws NoSuchMethodException */ public static Object jsRun(String methodName, String script, Object... args) throws ScriptException, NoSuchMethodException { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine javaScriptEngine = scriptEngineManager.getEngineByName("JavaScript"); javaScriptEngine.eval(script); Invocable inv = (Invocable) javaScriptEngine; return inv.invokeFunction(methodName, args); } }
如上我們就執行了一段javascript的代碼,實際執行了1000次,總耗時:3332毫秒 (基本就是3秒左右,跟機器的性能有關系,我用台式機執行在2.5秒左右,就不放截圖了)
由此可見使用java執行js腳本是有性能損耗的,但是如果我們能提前編譯腳本代碼的話,情況又是怎么樣呢
import javax.script.*; public class CompileJavaScriptTest { public static void main(String[] args) throws ScriptException, NoSuchMethodException { long l = System.currentTimeMillis(); String script = "function run(arg){if (arg>500){return 0}else{return arg}}"; ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine javaScriptEngine = scriptEngineManager.getEngineByName("JavaScript"); Compilable compilable = (Compilable) javaScriptEngine; CompiledScript compileScript = compilable.compile(script); for (int i = 0; i < 1000; i++) { System.out.println(jsRun("run", compileScript, i)); } System.out.println("耗時:" + String.valueOf(System.currentTimeMillis() - l)); } /** * @param methodName js腳本方法名 * @param compiledScript js 編譯腳本對象 * @param args js方法參數 * @return * @throws ScriptException * @throws NoSuchMethodException */ public static Object jsRun(String methodName, CompiledScript compiledScript, Object... args) throws ScriptException, NoSuchMethodException { compiledScript.eval(); Invocable inv = (Invocable) compiledScript.getEngine(); return inv.invokeFunction(methodName, args); } }
上面的代碼是先編譯腳本,再執行腳本,同樣的js腳本,同樣是執行1000次,耗時是476毫秒,可見比直接執行速度要快的多