mirror of https://github.com/golang/go.git
archive/zip: make benchmarks more representative
Currently zip benchmarks spend 60% in the rleBuffer code,
which is used only to test zip archive/zip itself:
17.48s 37.02% 37.02% 18.12s 38.37% archive/zip.(*rleBuffer).ReadAt
9.51s 20.14% 57.16% 10.43s 22.09% archive/zip.(*rleBuffer).Write
9.15s 19.38% 76.54% 10.85s 22.98% compress/flate.(*compressor).deflate
This means that benchmarks currently test performance of test helper.
Updating ReadAt/Write methods to be more performant makes benchmarks closer to real world.
name old time/op new time/op delta
CompressedZipGarbage-8 2.34ms ± 0% 2.34ms ± 1% ~ (p=0.684 n=10+10)
Zip64Test-8 58.1ms ± 2% 10.7ms ± 1% -81.54% (p=0.000 n=10+10)
Zip64TestSizes/4096-8 4.05µs ± 2% 3.65µs ± 5% -9.96% (p=0.000 n=9+10)
Zip64TestSizes/1048576-8 238µs ± 0% 43µs ± 0% -82.06% (p=0.000 n=10+10)
Zip64TestSizes/67108864-8 15.3ms ± 1% 2.6ms ± 0% -83.12% (p=0.000 n=10+9)
name old alloc/op new alloc/op delta
CompressedZipGarbage-8 17.9kB ±14% 16.0kB ±24% -10.48% (p=0.026 n=9+10)
name old allocs/op new allocs/op delta
CompressedZipGarbage-8 44.0 ± 0% 44.0 ± 0% ~ (all equal)
Change-Id: Idfd920d0e4bed4aec2f5be84dc7e3919d9f1dd2d
Reviewed-on: https://go-review.googlesource.com/83857
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
8999b1d6c9
commit
2629703a5c
|
|
@ -140,14 +140,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
|
||||||
rp = &r.buf[len(r.buf)-1]
|
rp = &r.buf[len(r.buf)-1]
|
||||||
// Fast path, if p is entirely the same byte repeated.
|
// Fast path, if p is entirely the same byte repeated.
|
||||||
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
|
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
|
||||||
all := true
|
if bytes.Count(p, []byte{lastByte}) == len(p) {
|
||||||
for _, b := range p {
|
|
||||||
if b != lastByte {
|
|
||||||
all = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if all {
|
|
||||||
rp.n += int64(len(p))
|
rp.n += int64(len(p))
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
@ -165,6 +158,25 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func min(x, y int) int {
|
||||||
|
if x < y {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
func memset(a []byte, b byte) {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Double, until we reach power of 2 >= len(a), same as bytes.Repeat,
|
||||||
|
// but without allocation.
|
||||||
|
a[0] = b
|
||||||
|
for i, l := 1, len(a); i < l; i *= 2 {
|
||||||
|
copy(a[i:], a[:i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -176,16 +188,13 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
parts := r.buf[skipParts:]
|
parts := r.buf[skipParts:]
|
||||||
if len(parts) > 0 {
|
if len(parts) > 0 {
|
||||||
skipBytes := off - parts[0].off
|
skipBytes := off - parts[0].off
|
||||||
for len(parts) > 0 {
|
for _, part := range parts {
|
||||||
part := parts[0]
|
repeat := min(int(part.n-skipBytes), len(p)-n)
|
||||||
for i := skipBytes; i < part.n; i++ {
|
memset(p[n:n+repeat], part.b)
|
||||||
if n == len(p) {
|
n += repeat
|
||||||
return
|
if n == len(p) {
|
||||||
}
|
return
|
||||||
p[n] = part.b
|
|
||||||
n++
|
|
||||||
}
|
}
|
||||||
parts = parts[1:]
|
|
||||||
skipBytes = 0
|
skipBytes = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue