]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: speed up makeslice by avoiding divisions
authorMartin Möhrmann <martisch@uos.de>
Sun, 10 Apr 2016 15:32:35 +0000 (17:32 +0200)
committerIan Lance Taylor <iant@golang.org>
Sun, 10 Apr 2016 23:39:46 +0000 (23:39 +0000)
Only compute the number of maximum allowed elements per slice once.

name         old time/op  new time/op  delta
MakeSlice-2  55.5ns ± 1%  45.6ns ± 2%  -17.88%  (p=0.000 n=99+100)

Change-Id: I951feffda5d11910a75e55d7e978d306d14da2c5
Reviewed-on: https://go-review.googlesource.com/21801
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/append_test.go
src/runtime/slice.go

index 3170870b0e559770dbb34a5929cf969c10c69ed1..6d7836a351677f85eb5a56d174fe9ca9bfdfd132 100644 (file)
@@ -7,6 +7,14 @@ import "testing"
 
 const N = 20
 
+func BenchmarkMakeSlice(b *testing.B) {
+       var x []byte
+       for i := 0; i < b.N; i++ {
+               x = make([]byte, 32)
+               _ = x
+       }
+}
+
 func BenchmarkGrowSliceBytes(b *testing.B) {
        b.StopTimer()
        var x = make([]byte, 9)
index 4ab221056c187f306074e965a72043545383cfc2..f36ec0b466ff367f78578176f311d708c791806e 100644 (file)
@@ -16,19 +16,27 @@ type slice struct {
 
 // TODO: take uintptrs instead of int64s?
 func makeslice(t *slicetype, len64, cap64 int64) slice {
-       // NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
+       // NOTE: The len > maxElements check here is not strictly necessary,
        // but it produces a 'len out of range' error instead of a 'cap out of range' error
        // when someone does make([]T, bignumber). 'cap out of range' is true too,
        // but since the cap is only being supplied implicitly, saying len is clearer.
        // See issue 4085.
+
+       maxElements := ^uintptr(0)
+       if t.elem.size > 0 {
+               maxElements = _MaxMem / t.elem.size
+       }
+
        len := int(len64)
-       if len64 < 0 || int64(len) != len64 || t.elem.size > 0 && uintptr(len) > _MaxMem/t.elem.size {
+       if len64 < 0 || int64(len) != len64 || uintptr(len) > maxElements {
                panic(errorString("makeslice: len out of range"))
        }
+
        cap := int(cap64)
-       if cap < len || int64(cap) != cap64 || t.elem.size > 0 && uintptr(cap) > _MaxMem/t.elem.size {
+       if cap < len || int64(cap) != cap64 || uintptr(cap) > maxElements {
                panic(errorString("makeslice: cap out of range"))
        }
+
        p := newarray(t.elem, uintptr(cap))
        return slice{p, len, cap}
 }