16

If you interpret the moment.js library using Nashorn on JDK 8, it runs in a couple of seconds:

time .../JDK8/bin/jjs moment-with-locales-2.22.2.js
real    0m2.644s
user    0m10.059s
sys     0m0.287s

But do the same on JDK 9 or 10, and it's terrible:

time .../JDK10/bin/jjs moment-with-locales-2.22.2.js
real    0m27.308s
user    0m59.690s
sys     0m1.353s

This is literally ten times slower. Is it just me?

I know Nashorn is going to be deprecated, but should it not work properly while it is supported?

Any suggestions? Workarounds?

David Conrad
  • 15,432
  • 2
  • 42
  • 54

1 Answers1

15

Nashorn can use 'optimistic types' (more below), and they are turned on by default in Java 9 and later, but they cause delays at startup.

Turning off optimistic types yields:

$ time jjs --optimistic-types=false moment-with-locales.js
real    0m4.282s
user    0m0.000s
sys     0m0.015s

The switch can be abbreviated -ot=false.

jjs -h defines optimistic types as follows:

Use optimistic type assumptions with deoptimizing recompilation. This makes the compiler try, for any program symbol whose type cannot be proven at compile time, to type it as narrow and primitive as possible. If the runtime encounters an error because symbol type is too narrow, a wider method will be generated until steady stage is reached. While this produces as optimal Java Bytecode as possible, erroneous type guesses will lead to longer warmup. Optimistic typing is currently enabled by default, but can be disabled for faster startup performance.

Thus, optimistic typing may yield faster performance in the long term (though that is not guaranteed), but results in slower startup.

David Conrad
  • 15,432
  • 2
  • 42
  • 54
  • Very interesting -- thank you for the pointer. I'm still kinda shocked that there is such a difference, but a bit more testing does confirm that this is only at startup. If you are executing the same JS code again and again, you only pay the price once, but it's a hefty price! I'm guessing that the compilation of moment.js is very expensive because it has to recompile many times. It's not that big (~50K), so that bodes ill for larger JS libraries. – Max Tardiveau Jul 30 '18 at 22:05
  • 1
    To follow up -- we are now disabling the optimistic types optimization by default by doing: `jsEngine = nashornEngineFactory.getScriptEngine(new String[] { "--optimistic-types=false" });` This allows us to have startup times that are more consistent with JDK 8, at the price of less optimization. Thanks again for the help! – Max Tardiveau Aug 01 '18 at 20:26
  • @MaxTardiveau You can accept my answer if it helped and answered your question. – David Conrad Aug 01 '18 at 20:45