]> Cypherpunks repositories - gostls13.git/commitdiff
archive/tar: add reader/writer benchmarks
authorAgniva De Sarker <agnivade@yahoo.co.in>
Sat, 12 Aug 2017 15:05:40 +0000 (20:35 +0530)
committerJoe Tsai <thebrokentoaster@gmail.com>
Wed, 16 Aug 2017 20:51:52 +0000 (20:51 +0000)
According to the discussion on golang.org/cl/55210,
adding benchmarks for reading from and writing to tar archives.

Splitting the benchmarks into 3 sections of USTAR, GNU, PAX each.

Results ran with -cpu=1 -count=10 on an amd64 machine (i5-5200U CPU @ 2.20GHz)
name           time/op
/Writer/USTAR  5.31µs ± 0%
/Writer/GNU    5.01µs ± 1%
/Writer/PAX    11.0µs ± 2%
/Reader/USTAR  3.22µs ± 1%
/Reader/GNU    3.04µs ± 1%
/Reader/PAX    7.48µs ± 1%

name           alloc/op
/Writer/USTAR  1.20kB ± 0%
/Writer/GNU    1.15kB ± 0%
/Writer/PAX    2.61kB ± 0%
/Reader/USTAR  1.38kB ± 0%
/Reader/GNU    1.35kB ± 0%
/Reader/PAX    4.91kB ± 0%

name           allocs/op
/Writer/USTAR    53.0 ± 0%
/Writer/GNU      47.0 ± 0%
/Writer/PAX       107 ± 0%
/Reader/USTAR    32.0 ± 0%
/Reader/GNU      30.0 ± 0%
/Reader/PAX      67.0 ± 0%

Change-Id: I58b1b85b52e58cbd566736aae4d722a3ddf2395b
Reviewed-on: https://go-review.googlesource.com/55254
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/archive/tar/tar_test.go

index 1a38ecb446b29ff90c0f29b12ff83939d30062fc..c64314491d7e2e9ba81ba5e5de4b3fb9e8c2b1a7 100644 (file)
@@ -7,6 +7,7 @@ package tar
 import (
        "bytes"
        "internal/testenv"
+       "io"
        "io/ioutil"
        "math"
        "os"
@@ -494,3 +495,96 @@ func TestHeaderAllowedFormats(t *testing.T) {
                }
        }
 }
+
+func Benchmark(b *testing.B) {
+       type file struct {
+               hdr  *Header
+               body []byte
+       }
+
+       vectors := []struct {
+               label string
+               files []file
+       }{{
+               "USTAR",
+               []file{{
+                       &Header{Name: "bar", Mode: 0640, Size: int64(3)},
+                       []byte("foo"),
+               }, {
+                       &Header{Name: "world", Mode: 0640, Size: int64(5)},
+                       []byte("hello"),
+               }},
+       }, {
+               "GNU",
+               []file{{
+                       &Header{Name: "bar", Mode: 0640, Size: int64(3), Devmajor: -1},
+                       []byte("foo"),
+               }, {
+                       &Header{Name: "world", Mode: 0640, Size: int64(5), Devmajor: -1},
+                       []byte("hello"),
+               }},
+       }, {
+               "PAX",
+               []file{{
+                       &Header{Name: "bar", Mode: 0640, Size: int64(3), Xattrs: map[string]string{"foo": "bar"}},
+                       []byte("foo"),
+               }, {
+                       &Header{Name: "world", Mode: 0640, Size: int64(5), Xattrs: map[string]string{"foo": "bar"}},
+                       []byte("hello"),
+               }},
+       }}
+
+       b.Run("Writer", func(b *testing.B) {
+               for _, v := range vectors {
+                       b.Run(v.label, func(b *testing.B) {
+                               b.ReportAllocs()
+                               for i := 0; i < b.N; i++ {
+                                       // Writing to ioutil.Discard because we want to
+                                       // test purely the writer code and not bring in disk performance into this.
+                                       tw := NewWriter(ioutil.Discard)
+                                       for _, file := range v.files {
+                                               if err := tw.WriteHeader(file.hdr); err != nil {
+                                                       b.Errorf("unexpected WriteHeader error: %v", err)
+                                               }
+                                               if _, err := tw.Write(file.body); err != nil {
+                                                       b.Errorf("unexpected Write error: %v", err)
+                                               }
+                                       }
+                                       if err := tw.Close(); err != nil {
+                                               b.Errorf("unexpected Close error: %v", err)
+                                       }
+                               }
+                       })
+               }
+       })
+
+       b.Run("Reader", func(b *testing.B) {
+               for _, v := range vectors {
+                       var buf bytes.Buffer
+                       var r bytes.Reader
+
+                       // Write the archive to a byte buffer.
+                       tw := NewWriter(&buf)
+                       for _, file := range v.files {
+                               tw.WriteHeader(file.hdr)
+                               tw.Write(file.body)
+                       }
+                       tw.Close()
+                       b.Run(v.label, func(b *testing.B) {
+                               b.ReportAllocs()
+                               // Read from the byte buffer.
+                               for i := 0; i < b.N; i++ {
+                                       r.Reset(buf.Bytes())
+                                       tr := NewReader(&r)
+                                       if _, err := tr.Next(); err != nil {
+                                               b.Errorf("unexpected Next error: %v", err)
+                                       }
+                                       if _, err := io.Copy(ioutil.Discard, tr); err != nil {
+                                               b.Errorf("unexpected Copy error : %v", err)
+                                       }
+                               }
+                       })
+               }
+       })
+
+}