Speed Execution with the Compilable Interface
A script engine typically evaluates a script via an interpreter, which consists of a front-end parser for parsing the script into intermediate code, and a back-end executor for executing this code. Because parsing the script into intermediate code must be performed each time the script is evaluated, there is an impact on performance.
Performance can be improved by having the script engine store the intermediate code for execution at a later time. To make this possible, the Scripting API provides a Compilable interface and a CompiledScript class. Compilable provides a pair of compile() methods that parse the script and generate the intermediate code, and return instances of CompiledScript subclasses that store this code. CompiledScript provides three eval() methods for executing the intermediate code. These methods do not parse the script.
Script engines that support this compilation feature implement the Compilable interface. Because not every engine will support compilation, it is important to test for this support before casting the engine to a Compilable, as follows:
ScriptEngine engine = … Compilable compilable = null; if (engine instanceof Compilable) compilable = (Compilable) engine;
To demonstrate the benefits of compilation, I've prepared an application that repeatedly evaluates a script through parsing and executing the intermediate code (for a specific number of iterations), compiles the script, and repeatedly evaluates the script by executing the intermediate code only (for the same number of iterations). Each loop is timed and the resulting time is output. Listing 6 presents the application's source code.
Listing 6: ScriptDemo6.java
One execution of ScriptDemo6 created the following output, which shows a boost in performance due to compilation: