• Justin Nuß's avatar
    encoding/csv: add option to reuse slices returned by Read · 2181653b
    Justin Nuß authored
    In many cases the records returned by Reader.Read will only be used between calls
    to Read and become garbage once a new record is read. In this case, instead of
    allocating a new slice on each call to Read, we can reuse the last allocated slice
    for successive calls to avoid unnecessary allocations.
    
    This change adds a new field ReuseRecord to the Reader struct to enable this reuse.
    
    ReuseRecord is false by default to avoid breaking existing code which dependss on
    the current behaviour.
    
    I also added 4 new benchmarks, corresponding to the existing Read benchmarks, which
    set ReuseRecord to true.
    
    Benchstat on my local machine (old is ReuseRecord = false, new is ReuseRecord = true)
    
    name                          old time/op    new time/op    delta
    Read-8                          2.75µs ± 2%    1.88µs ± 1%  -31.52%  (p=0.000 n=14+15)
    ReadWithFieldsPerRecord-8       2.75µs ± 0%    1.89µs ± 1%  -31.43%  (p=0.000 n=13+13)
    ReadWithoutFieldsPerRecord-8    2.77µs ± 1%    1.88µs ± 1%  -32.06%  (p=0.000 n=15+15)
    ReadLargeFields-8               55.4µs ± 1%    54.2µs ± 0%   -2.07%  (p=0.000 n=15+14)
    
    name                          old alloc/op   new alloc/op   delta
    Read-8                            664B ± 0%       24B ± 0%  -96.39%  (p=0.000 n=15+15)
    ReadWithFieldsPerRecord-8         664B ± 0%       24B ± 0%  -96.39%  (p=0.000 n=15+15)
    ReadWithoutFieldsPerRecord-8      664B ± 0%       24B ± 0%  -96.39%  (p=0.000 n=15+15)
    ReadLargeFields-8               3.94kB ± 0%    2.98kB ± 0%  -24.39%  (p=0.000 n=15+15)
    
    name                          old allocs/op  new allocs/op  delta
    Read-8                            18.0 ± 0%       8.0 ± 0%  -55.56%  (p=0.000 n=15+15)
    ReadWithFieldsPerRecord-8         18.0 ± 0%       8.0 ± 0%  -55.56%  (p=0.000 n=15+15)
    ReadWithoutFieldsPerRecord-8      18.0 ± 0%       8.0 ± 0%  -55.56%  (p=0.000 n=15+15)
    ReadLargeFields-8                 24.0 ± 0%      12.0 ± 0%  -50.00%  (p=0.000 n=15+15)
    
    Fixes #19721
    
    Change-Id: I79b14128bb9bb3465f53f40f93b1b528a9da6f58
    Reviewed-on: https://go-review.googlesource.com/41730Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
    Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    2181653b
reader_test.go 10.5 KB