From d9606e55328340b85c70bd7c15affc1c961c5b22 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Sat, 12 Aug 2017 20:35:40 +0530 Subject: [PATCH] archive/tar: add reader/writer benchmarks MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Run-TryBot: Joe Tsai TryBot-Result: Gobot Gobot --- src/archive/tar/tar_test.go | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/archive/tar/tar_test.go b/src/archive/tar/tar_test.go index 1a38ecb446..c64314491d 100644 --- a/src/archive/tar/tar_test.go +++ b/src/archive/tar/tar_test.go @@ -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) + } + } + }) + } + }) + +} -- 2.50.0