Commit d9606e55 authored by Agniva De Sarker's avatar Agniva De Sarker Committed by Joe Tsai

archive/tar: add reader/writer benchmarks

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/55254Reviewed-by: 's avatarJoe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 8127dbf7
...@@ -7,6 +7,7 @@ package tar ...@@ -7,6 +7,7 @@ package tar
import ( import (
"bytes" "bytes"
"internal/testenv" "internal/testenv"
"io"
"io/ioutil" "io/ioutil"
"math" "math"
"os" "os"
...@@ -494,3 +495,96 @@ func TestHeaderAllowedFormats(t *testing.T) { ...@@ -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)
}
}
})
}
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment