From: Carlo Alberto Ferraris Date: Sat, 24 Aug 2019 11:42:41 +0000 (+0900) Subject: math/rand: devirtualize interface call in Read X-Git-Tag: go1.14beta1~920 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5f1aeaeb77b36b92305b54acc4bd6a3319dce803;p=gostls13.git math/rand: devirtualize interface call in Read This allows to inline the common case in which the Source is a rngSource. On linux/amd64 in a VM: name old time/op new time/op delta Read3-4 33.8ns ± 8% 18.5ns ± 8% -45.38% (p=0.000 n=10+10) Read64-4 371ns ± 8% 70ns ± 7% -81.00% (p=0.000 n=10+10) Read1000-4 5.33µs ± 5% 0.86µs ± 3% -83.85% (p=0.000 n=9+9) Change-Id: Ibf47b0e9ecdfe62ffcb66d6a92f191800bdc740e Reviewed-on: https://go-review.googlesource.com/c/go/+/191539 Reviewed-by: Daniel Martí Reviewed-by: Brad Fitzpatrick Run-TryBot: Daniel Martí TryBot-Result: Gobot Gobot --- diff --git a/src/math/rand/rand.go b/src/math/rand/rand.go index 6e5eb4ba6a..3e44613663 100644 --- a/src/math/rand/rand.go +++ b/src/math/rand/rand.go @@ -261,15 +261,20 @@ func (r *Rand) Read(p []byte) (n int, err error) { if lk, ok := r.src.(*lockedSource); ok { return lk.read(p, &r.readVal, &r.readPos) } - return read(p, r.Int63, &r.readVal, &r.readPos) + return read(p, r.src, &r.readVal, &r.readPos) } -func read(p []byte, int63 func() int64, readVal *int64, readPos *int8) (n int, err error) { +func read(p []byte, src Source, readVal *int64, readPos *int8) (n int, err error) { pos := *readPos val := *readVal + rng, _ := src.(*rngSource) for n = 0; n < len(p); n++ { if pos == 0 { - val = int63() + if rng != nil { + val = rng.Int63() + } else { + val = src.Int63() + } pos = 7 } p[n] = byte(val) @@ -410,7 +415,7 @@ func (r *lockedSource) seedPos(seed int64, readPos *int8) { // read implements Read for a lockedSource without a race condition. func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) { r.lk.Lock() - n, err = read(p, r.src.Int63, readVal, readPos) + n, err = read(p, r.src, readVal, readPos) r.lk.Unlock() return }