RFR: 8314569: (fs) Improve normalization of UnixPath for directories [v2]

Sergey Tsypanov stsypanov at openjdk.org
Mon Aug 21 10:53:37 UTC 2023


On Mon, 21 Aug 2023 10:43:00 GMT, Sergey Tsypanov <stsypanov at openjdk.org> wrote:

>> Avoiding `String.substring()` call in `UnixPath.normalize()` can significantly reduce normalization costs for directories on Linux:
>> 
>> @BenchmarkMode(Mode.AverageTime)
>> @OutputTimeUnit(TimeUnit.NANOSECONDS)
>> @Warmup(time = 2, iterations = 5)
>> @Measurement(time = 2, iterations = 5)
>> @Fork(value = 4, jvmArgs = "-Xmx1g")
>> public class FileToPathBenchmark {
>> 
>>     @Benchmark
>>     public Path toDirectoryPath(Data data) {
>>         return FileSystems.getDefault().getPath(data.directoryPath);
>>     }
>> 
>>     @State(Scope.Thread)
>>     public static class Data {
>>         private String directoryPath = "/tmp/tmp/tmp/";
>>     }
>> }
>> 
>> Results:
>> 
>> baseline
>> 
>> Benchmark                                                             Mode  Cnt     Score     Error   Units
>> FileToPathBenchmark.toDirectoryPath                                   avgt   50    40.524 ±   0.940   ns/op
>> FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate                    avgt   50  3269.167 ± 101.018  MB/sec
>> FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate.norm               avgt   50   175.213 ±   1.200    B/op
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G1_Eden_Space           avgt   50  3279.401 ± 104.252  MB/sec
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G1_Eden_Space.norm      avgt   50   175.756 ±   1.681    B/op
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G1_Survivor_Space       avgt   50     0.006 ±   0.001  MB/sec
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G1_Survivor_Space.norm  avgt   50    ≈ 10⁻³              B/op
>> FileToPathBenchmark.toDirectoryPath:·gc.count                         avgt   50  1412.000            counts
>> FileToPathBenchmark.toDirectoryPath:·gc.time                          avgt   50  4144.000                ms
>> 
>> patched
>> 
>> Benchmark                                                             Mode  Cnt     Score     Error   Units
>> FileToPathBenchmark.toDirectoryPath                                   avgt   50    33.134 ±   2.313   ns/op
>> FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate                    avgt   50  2652.997 ± 152.758  MB/sec
>> FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate.norm               avgt   50   115.210 ±   1.960    B/op
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G1_Eden_Space           avgt   50  2654.258 ± 157.862  MB/sec
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G1_Eden_Space.norm      avgt   50   115.200 ±   1.960    B/op
>> FileToPathBenchmark.toDirectoryPath:·gc.churn.G...
>
> Sergey Tsypanov has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision:
> 
>  - Merge branch 'master' into unixpath-check-nn
>  - Further improvement
>  - Improve UnixPath normalization

Updated the PR. Checked cases for normal path (requires no normalization) and root:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(time = 2, iterations = 5)
@Measurement(time = 2, iterations = 5)
@Fork(value = 4, jvmArgs = "-Xmx1g")
public class FileToPathBenchmark {

    @Benchmark
    public Path toDirectoryPath(Data data) {
        return FileSystems.getDefault().getPath(data.directoryPath);
    }


    @Benchmark
    public Path toDirectoryPathDoubleSlash(Data data) {
        return FileSystems.getDefault().getPath(data.directoryPathWithDoubleSlash);
    }

    @Benchmark
    public Path toNormalPath(Data data) {
        return FileSystems.getDefault().getPath(data.normalPath);
    }

    @Benchmark
    public Path toRootPath(Data data) {
        return FileSystems.getDefault().getPath(data.rootPath);
    }

    @State(Scope.Thread)
    public static class Data {
        private final String rootPath = "/";
        private final String normalPath = "/tmp/tmp/tmp";
        private final String directoryPath = "/tmp/tmp/tmp/";
        private final String directoryPathWithDoubleSlash = "/tmp//tmp/tmp/";
    }
}

Results:

baseline

Benchmark                                                           Mode  Cnt     Score     Error   Units
FileToPathBenchmark.toDirectoryPath                                 avgt   20    44.993 ±   1.676   ns/op
FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate                  avgt   20  3732.628 ± 137.446  MB/sec
FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate.norm             avgt   20   176.000 ±   0.001    B/op
FileToPathBenchmark.toDirectoryPath:·gc.count                       avgt   20   234.000            counts
FileToPathBenchmark.toDirectoryPath:·gc.time                        avgt   20  1129.000                ms
FileToPathBenchmark.toDirectoryPathDoubleSlash                      avgt   20    58.963 ±   1.737   ns/op
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.alloc.rate       avgt   20  2717.169 ±  78.664  MB/sec
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.alloc.rate.norm  avgt   20   168.000 ±   0.001    B/op
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.count            avgt   20   190.000            counts
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.time             avgt   20   755.000                ms
FileToPathBenchmark.toNormalPath                                    avgt   20    14.017 ±   0.367   ns/op
FileToPathBenchmark.toNormalPath:·gc.alloc.rate                     avgt   20  2170.714 ±  52.098  MB/sec
FileToPathBenchmark.toNormalPath:·gc.alloc.rate.norm                avgt   20    32.000 ±   0.001    B/op
FileToPathBenchmark.toNormalPath:·gc.count                          avgt   20   163.000            counts
FileToPathBenchmark.toNormalPath:·gc.time                           avgt   20   695.000                ms
FileToPathBenchmark.toRootPath                                      avgt   20     5.679 ±   0.149   ns/op
FileToPathBenchmark.toRootPath:·gc.alloc.rate                       avgt   20  5372.970 ± 136.323  MB/sec
FileToPathBenchmark.toRootPath:·gc.alloc.rate.norm                  avgt   20    32.000 ±   0.001    B/op
FileToPathBenchmark.toRootPath:·gc.count                            avgt   20   259.000            counts
FileToPathBenchmark.toRootPath:·gc.time                             avgt   20  1105.000                ms

patched

Benchmark                                                           Mode  Cnt     Score     Error   Units
FileToPathBenchmark.toDirectoryPath                                 avgt   20    19.713 ±   0.338   ns/op
FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate                  avgt   20  3093.231 ±  52.488  MB/sec
FileToPathBenchmark.toDirectoryPath:·gc.alloc.rate.norm             avgt   20    64.000 ±   0.001    B/op
FileToPathBenchmark.toDirectoryPath:·gc.count                       avgt   20   211.000            counts
FileToPathBenchmark.toDirectoryPath:·gc.time                        avgt   20   914.000                ms
FileToPathBenchmark.toDirectoryPathDoubleSlash                      avgt   20    51.747 ±   3.485   ns/op
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.alloc.rate       avgt   20  2220.224 ± 141.430  MB/sec
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.alloc.rate.norm  avgt   20   120.000 ±   0.001    B/op
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.count            avgt   20   185.000            counts
FileToPathBenchmark.toDirectoryPathDoubleSlash:·gc.time             avgt   20   924.000                ms
FileToPathBenchmark.toNormalPath                                    avgt   20    14.052 ±   0.359   ns/op
FileToPathBenchmark.toNormalPath:·gc.alloc.rate                     avgt   20  2171.433 ±  54.694  MB/sec
FileToPathBenchmark.toNormalPath:·gc.alloc.rate.norm                avgt   20    32.000 ±   0.001    B/op
FileToPathBenchmark.toNormalPath:·gc.count                          avgt   20   164.000            counts
FileToPathBenchmark.toNormalPath:·gc.time                           avgt   20   852.000                ms
FileToPathBenchmark.toRootPath                                      avgt   20     5.922 ±   0.354   ns/op
FileToPathBenchmark.toRootPath:·gc.alloc.rate                       avgt   20  5169.978 ± 287.004  MB/sec
FileToPathBenchmark.toRootPath:·gc.alloc.rate.norm                  avgt   20    32.000 ±   0.001    B/op
FileToPathBenchmark.toRootPath:·gc.count                            avgt   20   245.000            counts
FileToPathBenchmark.toRootPath:·gc.time                             avgt   20  1244.000                ms

-------------

PR Comment: https://git.openjdk.org/jdk/pull/15342#issuecomment-1686097506


More information about the nio-dev mailing list