2012-08-31 21 views
10

Używam ScriptEngine w mojej aplikacji do oceny kodu klienta w mojej aplikacji. Problem polega na tym, że nie jest wystarczająco wydajny i muszę podjąć działania w celu poprawy czasu wykonania. Obecnie może to trwać do 1463ms (średnio około 300ms) do ewaluacji wyjątkowo prostego skryptu, który jest w zasadzie zastępowaniem parametrów w adresach URL.Z Java ScriptEngine (Groovy), jak uczynić go bardziej wydajnym?

Poszukuję prostych strategii, aby poprawić tę wydajność bez utraty zdolności skryptowania.

Po raz pierwszy pomyślałem, aby połączyć obiekt ScriptEngine i użyć go ponownie. Widzę w specyfikacji, że ma być ponownie wykorzystane, ale nie znalazłem żadnych przykładów ktoś faktycznie robi to.

Wszelkie pomysły? Oto mój kod:

ScriptEngineManager factory = new ScriptEngineManager(); 
GroovyScriptEngineImpl engine = (GroovyScriptEngineImpl)factory.getEngineByName("groovy"); 
engine.put("state", state; 
engine.put("zipcode", zip); 
engine.put("url", locationAwareAd.getLocationData().getGeneratedUrl()); 
url = (String) engine.eval(urlGeneratorScript); 

Wszelkie uwagi będą mile widziane!

Odpowiedz

12

Najprawdopodobniej problem polega na tym, że silnik faktycznie ocenia skrypt za każdym razem, gdy wywoływana jest funkcja eval(). Zamiast tego można ponownie użyć wstępnie skompilowanego skryptu za pośrednictwem interfejsu Compilable.

// move this into initialization part so that you do not call this every time. 
    ScriptEngineManager manager = new ScriptEngineManager(); 
    ScriptEngine engine = manager.getEngineByName("groovy"); 
    CompiledScript script = ((Compilable) engine).compile(urlGeneratorScript); 

    //the code below will use the precompiled script code 
    Bindings bindings = new Bindings(); 
    bindings.put("state", state; 
    bindings.put("zipcode", zip); 
    bindings.put("url", locationAwareAd.getLocationData().getGeneratedUrl()); 
    url = script.eval(bindings); 

FWIW, można również zaimplementować sprawdzanie znacznika czasu pliku, jeśli skrypt zostanie zmieniony, należy ponownie wywołać kompilację (..).

+0

Och, to świetny pomysł! Poszedłem do przodu i połączono ScriptEngine z basenem wspólnoty. Teraz idę i prekompiluj. Dzięki! – matsientst