From: Dmitriy Vyukov Date: Thu, 23 Jan 2014 20:13:21 +0000 (-0500) Subject: bufio: fix benchmarks behavior X-Git-Tag: go1.3beta1~881 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0ad2cd004c94c664dfee3ff16e9d587467f99883;p=gostls13.git bufio: fix benchmarks behavior Currently the benchmarks lie to testing package by doing O(N) work under StopTimer. And that hidden O(N) actually consitutes the bulk of benchmark work (e.g includes GC per iteration). This behavior accounts for windows-amd64-race builder hangs. Before: BenchmarkReaderCopyOptimal-4 1000000 1861 ns/op BenchmarkReaderCopyUnoptimal-4 500000 3327 ns/op BenchmarkReaderCopyNoWriteTo-4 50000 34549 ns/op BenchmarkWriterCopyOptimal-4 100000 16849 ns/op BenchmarkWriterCopyUnoptimal-4 500000 3126 ns/op BenchmarkWriterCopyNoReadFrom-4 50000 34609 ns/op ok bufio 65.273s After: BenchmarkReaderCopyOptimal-4 10000000 172 ns/op BenchmarkReaderCopyUnoptimal-4 10000000 267 ns/op BenchmarkReaderCopyNoWriteTo-4 100000 22905 ns/op BenchmarkWriterCopyOptimal-4 10000000 170 ns/op BenchmarkWriterCopyUnoptimal-4 10000000 226 ns/op BenchmarkWriterCopyNoReadFrom-4 100000 20575 ns/op ok bufio 14.074s Note the change in total time. LGTM=alex.brainman, rsc R=golang-codereviews, alex.brainman, rsc CC=golang-codereviews https://golang.org/cl/51360046 --- diff --git a/src/pkg/bufio/bufio_test.go b/src/pkg/bufio/bufio_test.go index 5cd030714d..06d365b796 100644 --- a/src/pkg/bufio/bufio_test.go +++ b/src/pkg/bufio/bufio_test.go @@ -1112,63 +1112,83 @@ func (w onlyWriter) Write(b []byte) (int, error) { func BenchmarkReaderCopyOptimal(b *testing.B) { // Optimal case is where the underlying reader implements io.WriterTo + srcBuf := bytes.NewBuffer(make([]byte, 8192)) + src := NewReader(srcBuf) + dstBuf := new(bytes.Buffer) + dst := onlyWriter{dstBuf} for i := 0; i < b.N; i++ { - b.StopTimer() - src := NewReader(bytes.NewBuffer(make([]byte, 8192))) - dst := onlyWriter{new(bytes.Buffer)} - b.StartTimer() + srcBuf.Reset() + src.Reset(srcBuf) + dstBuf.Reset() io.Copy(dst, src) } } func BenchmarkReaderCopyUnoptimal(b *testing.B) { // Unoptimal case is where the underlying reader doesn't implement io.WriterTo + srcBuf := bytes.NewBuffer(make([]byte, 8192)) + src := NewReader(onlyReader{srcBuf}) + dstBuf := new(bytes.Buffer) + dst := onlyWriter{dstBuf} for i := 0; i < b.N; i++ { - b.StopTimer() - src := NewReader(onlyReader{bytes.NewBuffer(make([]byte, 8192))}) - dst := onlyWriter{new(bytes.Buffer)} - b.StartTimer() + srcBuf.Reset() + src.Reset(onlyReader{srcBuf}) + dstBuf.Reset() io.Copy(dst, src) } } func BenchmarkReaderCopyNoWriteTo(b *testing.B) { + srcBuf := bytes.NewBuffer(make([]byte, 8192)) + srcReader := NewReader(srcBuf) + src := onlyReader{srcReader} + dstBuf := new(bytes.Buffer) + dst := onlyWriter{dstBuf} for i := 0; i < b.N; i++ { - b.StopTimer() - src := onlyReader{NewReader(bytes.NewBuffer(make([]byte, 8192)))} - dst := onlyWriter{new(bytes.Buffer)} - b.StartTimer() + srcBuf.Reset() + srcReader.Reset(srcBuf) + dstBuf.Reset() io.Copy(dst, src) } } func BenchmarkWriterCopyOptimal(b *testing.B) { // Optimal case is where the underlying writer implements io.ReaderFrom + srcBuf := bytes.NewBuffer(make([]byte, 8192)) + src := onlyReader{srcBuf} + dstBuf := new(bytes.Buffer) + dst := NewWriter(dstBuf) for i := 0; i < b.N; i++ { - b.StopTimer() - src := onlyReader{bytes.NewBuffer(make([]byte, 8192))} - dst := NewWriter(new(bytes.Buffer)) - b.StartTimer() + srcBuf.Reset() + dstBuf.Reset() + dst.Reset(dstBuf) io.Copy(dst, src) } } func BenchmarkWriterCopyUnoptimal(b *testing.B) { + srcBuf := bytes.NewBuffer(make([]byte, 8192)) + src := onlyReader{srcBuf} + dstBuf := new(bytes.Buffer) + dst := NewWriter(onlyWriter{dstBuf}) for i := 0; i < b.N; i++ { - b.StopTimer() - src := onlyReader{bytes.NewBuffer(make([]byte, 8192))} - dst := NewWriter(onlyWriter{new(bytes.Buffer)}) - b.StartTimer() + srcBuf.Reset() + dstBuf.Reset() + dst.Reset(onlyWriter{dstBuf}) io.Copy(dst, src) } } func BenchmarkWriterCopyNoReadFrom(b *testing.B) { + srcBuf := bytes.NewBuffer(make([]byte, 8192)) + src := onlyReader{srcBuf} + dstBuf := new(bytes.Buffer) + dstWriter := NewWriter(dstBuf) + dst := onlyWriter{dstWriter} for i := 0; i < b.N; i++ { - b.StopTimer() - src := onlyReader{bytes.NewBuffer(make([]byte, 8192))} - dst := onlyWriter{NewWriter(new(bytes.Buffer))} - b.StartTimer() + srcBuf.Reset() + dstBuf.Reset() + dstWriter.Reset(dstBuf) io.Copy(dst, src) } }