Commit 5f1aeaeb authored by Carlo Alberto Ferraris's avatar Carlo Alberto Ferraris Committed by Brad Fitzpatrick

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/+/191539Reviewed-by: default avatarDaniel Martí <mvdan@mvdan.cc>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 60f27135
......@@ -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
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment