Skip to content

Instantly share code, notes, and snippets.

@bnoordhuis
Created January 27, 2014 15:47
Show Gist options
  • Save bnoordhuis/8650904 to your computer and use it in GitHub Desktop.
Save bnoordhuis/8650904 to your computer and use it in GitHub Desktop.
// Copyright (c) 2014, Ben Noordhuis <[email protected]>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
function fib(n) {
return n > 1 ? fib(n - 1) + fib(n - 2) : n;
}
if (typeof print === 'undefined') {
print = console.log;
}
print(fib(42));
// Copyright (c) 2014, Ben Noordhuis <[email protected]>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Paths;
import java.nio.ByteBuffer;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
class nashorn {
public static void main(final String[] args) throws IOException {
final ScriptEngineManager manager = new ScriptEngineManager();
final NashornScriptEngineFactory factory = getScriptEngineFactory(manager);
if (factory == null) {
System.err.println("Nashorn script engine not found. Wrong JDK?");
System.exit(1);
}
// TODO(bnoordhuis) Parse Nashorn arguments and pass them to the engine.
final ScriptEngine engine = factory.getScriptEngine(new String[] {});
assert(engine != null); // Sanity check, cannot really fail.
if (args.length == 0) {
repl(engine);
} else {
// TODO(bnoordhuis) Pass extra arguments to script.
final Charset charset = Charset.forName("UTF-8");
final String script = slurp(args[0], charset);
final Object result = eval(engine, script);
if (result instanceof ScriptException) {
final ScriptException ex = (ScriptException) result;
ex.printStackTrace(System.err);
System.exit(1);
}
}
}
static void repl(final ScriptEngine engine) throws IOException {
// TODO(bnoordhuis) Respect current locale.
final Charset charset = Charset.forName("UTF-8");
final Reader reader = new InputStreamReader(System.in, charset);
final Writer writer = new OutputStreamWriter(System.out, charset);
repl(engine, reader, writer);
}
static void repl(final ScriptEngine engine, final Reader in, final Writer out) throws IOException {
final BufferedReader reader = new BufferedReader(in);
final PrintWriter writer = new PrintWriter(out);
while (true) {
writer.print("> ");
writer.flush();
final String line = reader.readLine();
if (line == null) {
break; // ^D
}
// TODO(bnoordhuis) Figure out how to discriminate between null and
// undefined. Nashorn currently returns null for both.
final Object result = eval(engine, line);
if (result != null) {
writer.println(result);
writer.flush();
}
}
}
static Object eval(final ScriptEngine engine, final String script) {
try {
return engine.eval(script);
} catch (ScriptException ex) {
return ex;
}
}
static String slurp(final String filename, final Charset charset) throws IOException {
final Path path = Paths.get(filename);
final byte[] bytes = Files.readAllBytes(path);
final ByteBuffer buffer = ByteBuffer.wrap(bytes);
return charset.decode(buffer).toString();
}
static NashornScriptEngineFactory getScriptEngineFactory(final ScriptEngineManager manager) {
for (final ScriptEngineFactory factory : manager.getEngineFactories()) {
if ("Oracle Nashorn".equals(factory.getEngineName()) &&
factory instanceof NashornScriptEngineFactory) {
return (NashornScriptEngineFactory) factory;
}
}
return null;
}
}
$ node -v
v0.10.25-pre
$ javac -version
javac 1.8.0-internal
# compile it
$ javac nashorn.java
# measure startup overhead
$ touch empty.js
# node startup overhead
$ perf stat -r10 node empty.js 2>&1 | grep 'seconds time elapsed'
0.036602302 seconds time elapsed ( +- 3.97% )
# nashorn/jvm startup overhead
$ perf stat -r10 java nashorn empty.js 2>&1 | grep 'seconds time elapsed'
1.317808207 seconds time elapsed ( +- 0.33% )
# node fib(42) performance
$ perf stat -r5 node fib.js 2>&1 | grep 'seconds time elapsed'
5.377733374 seconds time elapsed ( +- 0.36% )
# nashorn fib(42) performance
$ perf stat -r5 java nashorn fib.js 2>&1 | grep 'seconds time elapsed'
10.303278074 seconds time elapsed ( +- 2.22% )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment