• Martin Möhrmann's avatar
    runtime: simplify memory capacity check in growslice · 365594ad
    Martin Möhrmann authored
    Instead of comparing if the number of elements will
    not fit into memory check if the memory size of the
    slices backing memory is higher then the memory limit.
    
    This avoids a division or maxElems lookup.
    
    With et.size > 0:
       uintptr(newcap)                > maxSliceCap(et.size)
    -> uintptr(int(capmem / et.size)) > _MaxMem  /  et.size
    ->             capmem / et.size   > _MaxMem  /  et.size
    ->             capmem             > _MaxMem
    
    Note that due to integer division from capmem > _MaxMem
    it does not follow that uintptr(newcap) > maxSliceCap(et.size).
    
    Consolidated runtime GrowSlice benchmarks by using sub-benchmarks and
    added more struct sizes to show performance improvement when division
    is avoided for element sizes larger than 32 bytes.
    
    AMD64:
    GrowSlice/Byte       38.9ns ± 2%  38.9ns ± 1%    ~     (p=0.974 n=20+20)
    GrowSlice/Int        58.3ns ± 3%  58.0ns ± 2%    ~     (p=0.154 n=20+19)
    GrowSlice/Ptr        95.7ns ± 2%  95.1ns ± 2%  -0.60%  (p=0.034 n=20+20)
    GrowSlice/Struct/24  95.4ns ± 1%  93.9ns ± 1%  -1.54%  (p=0.000 n=19+19)
    GrowSlice/Struct/32   110ns ± 1%   108ns ± 1%  -1.76%  (p=0.000 n=19+20)
    GrowSlice/Struct/40   138ns ± 1%   128ns ± 1%  -7.09%  (p=0.000 n=20+20)
    
    Change-Id: I1c37857c74ea809da373e668791caffb6a5cbbd3
    Reviewed-on: https://go-review.googlesource.com/53471
    Run-TryBot: Martin Möhrmann <moehrmann@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarKeith Randall <khr@golang.org>
    365594ad
slice.go 6.02 KB