aboutsummaryrefslogtreecommitdiff
path: root/src/archive
diff options
context:
space:
mode:
authorIlya Tocar <ilya.tocar@intel.com>2017-12-13 15:25:50 -0600
committerBrad Fitzpatrick <bradfitz@golang.org>2018-02-21 00:32:33 +0000
commit2629703a5c36210435369e0dc24db6497ea059a8 (patch)
tree486974fee6f238d5068af02d998fcf306e4a0623 /src/archive
parent8999b1d6c9be053f0e8c07ac3516eef7dc8a1830 (diff)
downloadgo-2629703a5c36210435369e0dc24db6497ea059a8.tar.gz
go-2629703a5c36210435369e0dc24db6497ea059a8.zip
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>
Diffstat (limited to 'src/archive')
-rw-r--r--src/archive/zip/zip_test.go43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/archive/zip/zip_test.go b/src/archive/zip/zip_test.go
index 7e02cb0eea..5adb87d5e3 100644
--- a/src/archive/zip/zip_test.go
+++ b/src/archive/zip/zip_test.go
@@ -140,14 +140,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
rp = &r.buf[len(r.buf)-1]
// Fast path, if p is entirely the same byte repeated.
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
- all := true
- for _, b := range p {
- if b != lastByte {
- all = false
- break
- }
- }
- if all {
+ if bytes.Count(p, []byte{lastByte}) == len(p) {
rp.n += int64(len(p))
return len(p), nil
}
@@ -165,6 +158,25 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
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) {
if len(p) == 0 {
return
@@ -176,16 +188,13 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
parts := r.buf[skipParts:]
if len(parts) > 0 {
skipBytes := off - parts[0].off
- for len(parts) > 0 {
- part := parts[0]
- for i := skipBytes; i < part.n; i++ {
- if n == len(p) {
- return
- }
- p[n] = part.b
- n++
+ for _, part := range parts {
+ repeat := min(int(part.n-skipBytes), len(p)-n)
+ memset(p[n:n+repeat], part.b)
+ n += repeat
+ if n == len(p) {
+ return
}
- parts = parts[1:]
skipBytes = 0
}
}