What is Nashorn?
Nashorn, pronounced "Nass-horn", was the name of a German tank during World War II, and also the java8 new generation of JavaScript engines-replacing the old, slow rhino, in accordance with the ECMASCRIPT-262 5.1 Edition language Specification. You might want JavaScript to be running in a Web browser that provides various DOM operations on HTML, but Nashorn does not support browser DOM objects. This is a point to note.
Getting Started with Nashorn
There are mainly two aspects, the JJS tool and the following API for the Javax.script package:
JJS is brought under Java_home/bin, as an example, let's create a func.js with the following:
1234 |
function f() { return 1 ; }; print( f() + 1 ); |
Run this file and pass the file as a parameter to JJS
Output results: 2
Another aspect is Javax.script, which is also the API left by the previous rhino
1234 |
ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName( "JavaScript" ); System.out.println( engine.getClass().getName() ); System.out.println( "Result:" + engine.eval( "function f() { return 1; }; f() + 1;" ) ); |
The output is as follows:
123 |
jdk.nashorn.api.scripting.NashornScriptEngine Result: 2 Nashorn VS Rhino |
JavaScript is no longer new in the JVM, and rhino already exists at JDK6, but why instead of rhino, the official explanation is that rhino is too slow compared to other JavaScript engines (like Google's V8). It's better to rewrite rhino than to change it. Since performance is a bright spot of nashorn, below test performance comparison, in order to compare the performance between the two, need to use Esprima, a ECMAScript parsing framework, used to parse the uncompressed version of jquery (about 268kb), the test core code is as follows:
12345678910111213141516171819202122232425262728293031323334353637383940 |
static
void
rhino(String parser, String code) {
String source =
"speedtest"
;
int
line =
1
;
Context context = Context.enter();
context.setOptimizationLevel(
9
);
try
{
Scriptable scope = context.initStandardObjects();
context.evaluateString(scope, parser, source, line,
null
);
ScriptableObject.putProperty(scope,
"$code"
, Context.javaToJS(code, scope));
Object tree =
new
Object();
Object tokens =
new
Object();
for
(
int
i =
0
; i < RUNS; ++i) {
long
start = System.nanoTime();
tree = context.evaluateString(scope,
"esprima.parse($code)"
, source, line,
null
);
tokens = context.evaluateString(scope,
"esprima.tokenize($code)"
, source, line,
null
);
long
stop = System.nanoTime();
System.out.println(
"Run #"
+ (i +
1
) +
": "
+ Math.round((stop - start) / 1e6) +
" ms"
);
}
}
finally
{
Context.exit();
System.gc();
}
}
static
void nashorn(String parser, String code)
throws
ScriptException,NoSuchMethodException {
ScriptEngineManager factory =
new
ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName(
"nashorn"
);
engine.eval(parser);
Invocable inv = (Invocable) engine;
Object esprima = engine.get(
"esprima"
);
Object tree =
new
Object();
Object tokens =
new
Object();
for (
int
i =
0
; i < RUNS; ++i) {
long
start = System.nanoTime();
tree = inv.invokeMethod(esprima,
"parse"
, code);
tokens = inv.invokeMethod(esprima,
"tokenize"
, code);
long
stop = System.nanoTime();
System.out.println(
"Run #"
+ (i +
1
) +
": "
+ Math.round((stop - start) / 1e6) +
" ms"
);
}
// System.out.println("Data is " + tokens.toString() + " and " + tree.toString());
}
|
As can be seen from the code, the tester executes Esprima's parse and tokenize to run the contents of the test file, and Rhino and Nashorn execute 30 times respectively, and at the beginning, Rhino needs 1726 MS and slowly accelerates, eventually stabilizing at around 950ms, Nashorn has another feature, the first time it takes 3682ms to run, but it quickly accelerates after a warm-up, and eventually runs stably at 175MS, as shown in
Nashorn first compiles JavaScript code into Java bytecode, then runs on the JVM, and the underlying is executed using the invokedynamic command, so the speed is very strong.
Why use Java to implement JavaScript
This is also a point of concern to most of the students, I agree with the view is:
1. Mature GC
2. The mature JIT compiler
3. Multithreading support
4. Extensive library of standards and third-party libraries
To take full advantage of the existing resources of the Java platform.
Summarize
The new rhino can be said to be a rhino-style chariot, a lot faster than rhino, as a high-performance JavaScript operating environment, nashorn a lot of possibilities.
For example, Avatar.js is dependent on Nashorn to support the implementation of the node. JS programming model on the JVM, plus additional new features such as multi-event loops with a built-in load balancer and a lightweight messaging mechanism using multithreading; Avatar also provides a model-store, JPA-based, purely JavaScript ORM framework.
Another way to borrow power in the enterprise Nashorn is scripting, and we can now use JavaScript scripts to interact with Java, and even use Nashorn to monitor server health through the rest interface, compared to the usual shell scripts like Linux.
A detailed example of the new Java feature Nashorn