Skip to content
Snippets Groups Projects
  • Tom Thorogood's avatar
    9e7bc80b
    os: reuse readdir buffers on unix with a sync.Pool · 9e7bc80b
    Tom Thorogood authored
    (*File).readdir allocates a fixed-size 8KiB buffer on unix systems that
    cannot be reused. While it accounts for just a single allocation, it's
    more than large enough to show up in profiles and make things quite a
    bit slower.
    
    Instead of allocating so often, use a sync.Pool to allow these buffers to
    be reused. This has a large impact on readdir heavy workloads.
    
    Package os benchmarks:
    
    name            old time/op    new time/op    delta
    Readdirname-12    35.6µs ± 5%    18.1µs ± 4%  -49.00%  (p=0.000 n=10+10)
    Readdir-12         142µs ± 1%     121µs ± 0%  -14.87%  (p=0.000 n=10+9)
    ReadDir-12        44.0µs ± 6%    28.4µs ± 8%  -35.58%  (p=0.000 n=9+10)
    
    name            old alloc/op   new alloc/op   delta
    Readdirname-12    14.4kB ± 0%     6.2kB ± 0%  -57.08%  (p=0.000 n=10+10)
    Readdir-12        41.6kB ± 0%    33.4kB ± 0%  -19.77%  (p=0.000 n=10+9)
    ReadDir-12        21.9kB ± 0%    13.7kB ± 0%  -37.39%  (p=0.000 n=10+10)
    
    name            old allocs/op  new allocs/op  delta
    Readdirname-12       131 ± 0%       130 ± 0%   -0.76%  (p=0.000 n=10+10)
    Readdir-12           367 ± 0%       366 ± 0%   -0.27%  (p=0.000 n=10+10)
    ReadDir-12           249 ± 0%       248 ± 0%   -0.40%  (p=0.000 n=10+10)
    
    A clunky benchmark I threw together that calls filepath.WalkDir on $GOMODCACHE:
    
    name        old time/op    new time/op    delta
    WalkDir-12    91.2ms ±19%    48.7ms ± 0%  -46.54%  (p=0.000 n=10+10)
    
    name        old alloc/op   new alloc/op   delta
    WalkDir-12    54.0MB ± 0%     7.6MB ± 0%  -85.92%  (p=0.000 n=8+9)
    
    name        old allocs/op  new allocs/op  delta
    WalkDir-12      136k ± 0%      130k ± 0%   -4.15%  (p=0.000 n=8+8)
    
    Change-Id: I00e4d48726da0e46c528ab205409afd03127b844
    Reviewed-on: https://go-review.googlesource.com/c/go/+/302169
    
    
    Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
    Reviewed-by: default avatarEmmanuel Odeke <emmanuel@orijtech.com>
    Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
    TryBot-Result: Go Bot <gobot@golang.org>
    9e7bc80b
    History
    os: reuse readdir buffers on unix with a sync.Pool
    Tom Thorogood authored
    (*File).readdir allocates a fixed-size 8KiB buffer on unix systems that
    cannot be reused. While it accounts for just a single allocation, it's
    more than large enough to show up in profiles and make things quite a
    bit slower.
    
    Instead of allocating so often, use a sync.Pool to allow these buffers to
    be reused. This has a large impact on readdir heavy workloads.
    
    Package os benchmarks:
    
    name            old time/op    new time/op    delta
    Readdirname-12    35.6µs ± 5%    18.1µs ± 4%  -49.00%  (p=0.000 n=10+10)
    Readdir-12         142µs ± 1%     121µs ± 0%  -14.87%  (p=0.000 n=10+9)
    ReadDir-12        44.0µs ± 6%    28.4µs ± 8%  -35.58%  (p=0.000 n=9+10)
    
    name            old alloc/op   new alloc/op   delta
    Readdirname-12    14.4kB ± 0%     6.2kB ± 0%  -57.08%  (p=0.000 n=10+10)
    Readdir-12        41.6kB ± 0%    33.4kB ± 0%  -19.77%  (p=0.000 n=10+9)
    ReadDir-12        21.9kB ± 0%    13.7kB ± 0%  -37.39%  (p=0.000 n=10+10)
    
    name            old allocs/op  new allocs/op  delta
    Readdirname-12       131 ± 0%       130 ± 0%   -0.76%  (p=0.000 n=10+10)
    Readdir-12           367 ± 0%       366 ± 0%   -0.27%  (p=0.000 n=10+10)
    ReadDir-12           249 ± 0%       248 ± 0%   -0.40%  (p=0.000 n=10+10)
    
    A clunky benchmark I threw together that calls filepath.WalkDir on $GOMODCACHE:
    
    name        old time/op    new time/op    delta
    WalkDir-12    91.2ms ±19%    48.7ms ± 0%  -46.54%  (p=0.000 n=10+10)
    
    name        old alloc/op   new alloc/op   delta
    WalkDir-12    54.0MB ± 0%     7.6MB ± 0%  -85.92%  (p=0.000 n=8+9)
    
    name        old allocs/op  new allocs/op  delta
    WalkDir-12      136k ± 0%      130k ± 0%   -4.15%  (p=0.000 n=8+8)
    
    Change-Id: I00e4d48726da0e46c528ab205409afd03127b844
    Reviewed-on: https://go-review.googlesource.com/c/go/+/302169
    
    
    Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
    Reviewed-by: default avatarEmmanuel Odeke <emmanuel@orijtech.com>
    Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
    TryBot-Result: Go Bot <gobot@golang.org>
Code owners
Assign users and groups as approvers for specific file changes. Learn more.