Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8143347

Evaluating JavaScript under Nashorn is slow in comparison to Rhino

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.9.0-ea"
      Java(TM) SE Runtime Environment (build 1.9.0-ea-b91)
      Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b91, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      I have a Java program which makes use of JSR-223 and JavaScript. It calls ScriptEngine.eval() multiple times as it is processing user provided JavaScript to process templates - each template has multiple script blocks which are each evaluated and the template is processed multiple times for multiple rows of data. I have noticed that Java 8 (Nashorn) is significantly slower in comparison to Java 7 (Rhino) when evaluating JavaScript. Hoping the the performance might have been improved with Java 9, it appears to be 3x slower on Build 91.

      Possible duplicate of JDK-8034959, but it hasn't been commented on since 2014 and I am seeing even worst performance in Java 9.

      REGRESSION. Last worked in version 7u80

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.7.0_80"
      Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the attached program under Java 7, Java 8 and Java 9 to see the difference.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I understand that Nashorn takes more time to eval code as it compiles the code first to try and improve performance of the script itself. This has a negative impact on use cases that use a lot of evals.

      I would expect to see similar results to Rhino, but I would expect the same or better performance with Java 9 compared to Java 8.
      ACTUAL -
      D:\Scripts>java7 SSCCE
      Warming Up...
      Starting...
      Elapsed Time: 0.58447784

      D:\Scripts>java8 SSCCE
      Warming Up...
      Starting...
      Elapsed Time: 5.0787277

      D:\Scripts>java9 SSCCE
      Warming Up...
      Starting...
      Elapsed Time: 12.828292

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.script.*;

      public class SSCCE {
        public SSCCE() {
          ScriptEngineManager sem = new ScriptEngineManager();
          ScriptEngine js = sem.getEngineByName("JavaScript");
          long t = 0;
          int i = 0;

          String gJs = "function ip2long(ip) {";
          gJs += "var aIP = ip.split(\".\");";
          gJs += "return (aIP[0] * Math.pow(256, 3)) + (aIP[1] * Math.pow(256, 2)) + (aIP[2] * 256) + (aIP[3] * 1);";
          gJs += "}";
          gJs += "function long2ip(l) {";
          gJs += "if (!isNaN(l) && ((l >= 0) || (l <= Math.pow(2, 32)))) {";
          gJs += "return Math.floor(l / Math.pow(256, 3)) + \".\" +";
          gJs += "Math.floor((l % Math.pow(256, 3)) / Math.pow(256, 2)) + \".\" +";
          gJs += "Math.floor(((l % Math.pow(256, 3)) % Math.pow(256, 2)) / Math.pow(256, 1)) + \".\" +";
          gJs += "Math.floor((((l % Math.pow(256, 3)) % Math.pow(256, 2)) % Math.pow(256, 1)) / Math.pow(256, 0));";
          gJs += "}";
          gJs += "return null;";
          gJs += "}";

          try {
            js.eval(gJs);
          }
          catch (Exception e) {
            e.printStackTrace();
          }

          System.out.println("Warming Up...");

          t = System.nanoTime();

          for (i = 0; i < 4097; i++) {
            try {
              String sJs = "var ip = \"192.0.2.0\";";
              sJs += "var nip = long2ip(ip2long(ip, " + i + "));";
              js.eval(sJs);
            }
            catch (Exception e) {
              e.printStackTrace();
            }
          }

          System.out.println("Starting...");

          t = System.nanoTime();

          for (i = 0; i < 4097; i++) {
            try {
              String sJs = "var ip = \"192.0.2.0\";";
              sJs += "var nip = long2ip(ip2long(ip, " + i + "));";
              js.eval(sJs);
            }
            catch (Exception e) {
              e.printStackTrace();
            }
          }

          System.out.println("Elapsed Time: " + (System.nanoTime() - t) / 1000000000.0f);
        }

        public static void main(String[] args) {
          new SSCCE();
        }
      }
      ---------- END SOURCE ----------

            hannesw Hannes Wallnoefer
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: