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

Significant performance regression in File.getCanonicalFile, getCanonicalPath

    Details

    • Subcomponent:
    • Introduced In Build:
      b03
    • Introduced In Version:
      12
    • CPU:
      generic
    • OS:
      generic

      Description

      ADDITIONAL SYSTEM INFORMATION :
      Regression observed with

      Ubuntu 20.04 with Java 12, Java 16 early access build 25 (both from jdk.java.net)
      Windows 10 with Java 12, Java 16 early access build 25 (both from jdk.java.net)
      macOS 10.15.7 with Java 15, Java 16 early access build 25 (both from jdk.java.net)

      A DESCRIPTION OF THE PROBLEM :
      File.getCanonicalFile and getCanonicalPath seem to have regressed significantly in Java 12 compared to Java 11.
      I ran a small "benchmark" on Linux, macOS and Windows. The results are:

      Linux Java 11: 1027ms, Java 12: 11559ms
      macOS Java 11: 1035ms, Java 15: 112198ms
      Windows Java 11: 1245ms, Java 12: 525467ms

      The numbers with Java 16 early access build 25 are similar to Java 12.
      I used reference implementations from jdk.java.net for all the tests.

      As you can see, the performance regression ranges from 10x to 50x (Windows). For code that process many paths, this can be a major bottleneck, which wasn't significant before.

      REGRESSION : Last worked in version 11.0.9

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the code snippet included in this report, compare Java 11 to newer versions.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      File.getCanonicalFile, getCanonicalPath performance should not regress significantly.
      ACTUAL -
      File.getCanonicalFile, getCanonicalPath are 10-50 times slower, depending on the OS.

      ---------- BEGIN SOURCE ----------
      import java.io.File;
      import java.io.IOException;

      public class Test {

      public static void main(String[] args) {
      long oldTime = System.currentTimeMillis();
      try {
      for (int i = 0; i < 10000000; i++) {
      new File("/tmp/../").getCanonicalFile();
      }
      } catch (IOException e) {
      }
      long newTime = System.currentTimeMillis() - oldTime;
      System.out.println(newTime);
      }
      }

      ---------- END SOURCE ----------

      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: