]> Cypherpunks repositories - gostls13.git/commitdiff
math/rand: devirtualize interface call in Read
authorCarlo Alberto Ferraris <cafxx@strayorange.com>
Sat, 24 Aug 2019 11:42:41 +0000 (20:42 +0900)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 30 Sep 2019 15:43:34 +0000 (15:43 +0000)
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í <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/math/rand/rand.go

index 6e5eb4ba6ade8e9f39bc95032a42f4df8dc9cc91..3e44613663fba010b4f6e1a4a40396a627927d97 100644 (file)
@@ -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
 }