xoofx / zio

A cross-platform abstract/virtual filesystem framework with many built-ins filesystems for .NET
BSD 2-Clause "Simplified" License
806 stars 61 forks source link

Reduce allocations in UPath.Combine #89

Closed GerardSmit closed 1 month ago

GerardSmit commented 1 month ago

This PR reduces the allocations in .NET 7 and higher

Benchmark

BenchmarkRunner.Run<Benchmark>();

[MemoryDiagnoser]
public class Benchmark
{
    [Benchmark] public UPath Combine2() => UPath.Combine("/a", "b");
    [Benchmark] public UPath Combine3() => UPath.Combine("/a", "b", "c");
    [Benchmark] public UPath Combine4() => UPath.Combine("/a", "b", "c", "d");
    [Benchmark] public UPath Combine5() => UPath.Combine("/a", "b", "c", "d", "e");

    [Benchmark] public UPath Combine2WithAbsolute() => UPath.Combine("/a", "/b");
    [Benchmark] public UPath Combine3WithAbsolute() => UPath.Combine("/a", "b", "/c");
    [Benchmark] public UPath Combine4WithAbsolute() => UPath.Combine("/a", "b", "c", "/d");
    [Benchmark] public UPath Combine5WithAbsolute() => UPath.Combine("/a", "b", "c", "d", "/e");
}

Before

Method Mean Error StdDev Gen0 Allocated
Combine2 37.39 ns 0.267 ns 0.250 ns 0.0019 32 B
Combine3 66.89 ns 0.415 ns 0.388 ns 0.0043 72 B
Combine4 106.16 ns 1.653 ns 1.546 ns 0.0062 104 B
Combine5 145.36 ns 1.328 ns 1.242 ns 0.0134 224 B
Combine2WithAbsolute 15.62 ns 0.072 ns 0.067 ns - -
Combine3WithAbsolute 46.70 ns 0.804 ns 0.752 ns 0.0019 32 B
Combine4WithAbsolute 58.17 ns 0.912 ns 0.853 ns 0.0019 32 B
Combine5WithAbsolute 122.32 ns 1.402 ns 1.311 ns 0.0105 176 B

After

Method Mean Error StdDev Gen0 Allocated
Combine2 34.48 ns 0.292 ns 0.259 ns 0.0019 32 B
Combine3 47.70 ns 0.201 ns 0.178 ns 0.0024 40 B
Combine4 64.36 ns 0.485 ns 0.430 ns 0.0024 40 B
Combine5 146.00 ns 1.028 ns 0.802 ns 0.0134 224 B
Combine2WithAbsolute 15.94 ns 0.058 ns 0.051 ns - -
Combine3WithAbsolute 27.21 ns 0.088 ns 0.078 ns - -
Combine4WithAbsolute 37.27 ns 0.060 ns 0.050 ns - -
Combine5WithAbsolute 125.59 ns 0.470 ns 0.392 ns 0.0105 176 B