Skip to content

Commit 0ad2cd0

Browse files
dvyukovrsc
authored andcommitted
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
1 parent 672ab62 commit 0ad2cd0

File tree

1 file changed

+44
-24
lines changed

1 file changed

+44
-24
lines changed

src/pkg/bufio/bufio_test.go

+44-24
Original file line numberDiff line numberDiff line change
@@ -1112,63 +1112,83 @@ func (w onlyWriter) Write(b []byte) (int, error) {
11121112

11131113
func BenchmarkReaderCopyOptimal(b *testing.B) {
11141114
// Optimal case is where the underlying reader implements io.WriterTo
1115+
srcBuf := bytes.NewBuffer(make([]byte, 8192))
1116+
src := NewReader(srcBuf)
1117+
dstBuf := new(bytes.Buffer)
1118+
dst := onlyWriter{dstBuf}
11151119
for i := 0; i < b.N; i++ {
1116-
b.StopTimer()
1117-
src := NewReader(bytes.NewBuffer(make([]byte, 8192)))
1118-
dst := onlyWriter{new(bytes.Buffer)}
1119-
b.StartTimer()
1120+
srcBuf.Reset()
1121+
src.Reset(srcBuf)
1122+
dstBuf.Reset()
11201123
io.Copy(dst, src)
11211124
}
11221125
}
11231126

11241127
func BenchmarkReaderCopyUnoptimal(b *testing.B) {
11251128
// Unoptimal case is where the underlying reader doesn't implement io.WriterTo
1129+
srcBuf := bytes.NewBuffer(make([]byte, 8192))
1130+
src := NewReader(onlyReader{srcBuf})
1131+
dstBuf := new(bytes.Buffer)
1132+
dst := onlyWriter{dstBuf}
11261133
for i := 0; i < b.N; i++ {
1127-
b.StopTimer()
1128-
src := NewReader(onlyReader{bytes.NewBuffer(make([]byte, 8192))})
1129-
dst := onlyWriter{new(bytes.Buffer)}
1130-
b.StartTimer()
1134+
srcBuf.Reset()
1135+
src.Reset(onlyReader{srcBuf})
1136+
dstBuf.Reset()
11311137
io.Copy(dst, src)
11321138
}
11331139
}
11341140

11351141
func BenchmarkReaderCopyNoWriteTo(b *testing.B) {
1142+
srcBuf := bytes.NewBuffer(make([]byte, 8192))
1143+
srcReader := NewReader(srcBuf)
1144+
src := onlyReader{srcReader}
1145+
dstBuf := new(bytes.Buffer)
1146+
dst := onlyWriter{dstBuf}
11361147
for i := 0; i < b.N; i++ {
1137-
b.StopTimer()
1138-
src := onlyReader{NewReader(bytes.NewBuffer(make([]byte, 8192)))}
1139-
dst := onlyWriter{new(bytes.Buffer)}
1140-
b.StartTimer()
1148+
srcBuf.Reset()
1149+
srcReader.Reset(srcBuf)
1150+
dstBuf.Reset()
11411151
io.Copy(dst, src)
11421152
}
11431153
}
11441154

11451155
func BenchmarkWriterCopyOptimal(b *testing.B) {
11461156
// Optimal case is where the underlying writer implements io.ReaderFrom
1157+
srcBuf := bytes.NewBuffer(make([]byte, 8192))
1158+
src := onlyReader{srcBuf}
1159+
dstBuf := new(bytes.Buffer)
1160+
dst := NewWriter(dstBuf)
11471161
for i := 0; i < b.N; i++ {
1148-
b.StopTimer()
1149-
src := onlyReader{bytes.NewBuffer(make([]byte, 8192))}
1150-
dst := NewWriter(new(bytes.Buffer))
1151-
b.StartTimer()
1162+
srcBuf.Reset()
1163+
dstBuf.Reset()
1164+
dst.Reset(dstBuf)
11521165
io.Copy(dst, src)
11531166
}
11541167
}
11551168

11561169
func BenchmarkWriterCopyUnoptimal(b *testing.B) {
1170+
srcBuf := bytes.NewBuffer(make([]byte, 8192))
1171+
src := onlyReader{srcBuf}
1172+
dstBuf := new(bytes.Buffer)
1173+
dst := NewWriter(onlyWriter{dstBuf})
11571174
for i := 0; i < b.N; i++ {
1158-
b.StopTimer()
1159-
src := onlyReader{bytes.NewBuffer(make([]byte, 8192))}
1160-
dst := NewWriter(onlyWriter{new(bytes.Buffer)})
1161-
b.StartTimer()
1175+
srcBuf.Reset()
1176+
dstBuf.Reset()
1177+
dst.Reset(onlyWriter{dstBuf})
11621178
io.Copy(dst, src)
11631179
}
11641180
}
11651181

11661182
func BenchmarkWriterCopyNoReadFrom(b *testing.B) {
1183+
srcBuf := bytes.NewBuffer(make([]byte, 8192))
1184+
src := onlyReader{srcBuf}
1185+
dstBuf := new(bytes.Buffer)
1186+
dstWriter := NewWriter(dstBuf)
1187+
dst := onlyWriter{dstWriter}
11671188
for i := 0; i < b.N; i++ {
1168-
b.StopTimer()
1169-
src := onlyReader{bytes.NewBuffer(make([]byte, 8192))}
1170-
dst := onlyWriter{NewWriter(new(bytes.Buffer))}
1171-
b.StartTimer()
1189+
srcBuf.Reset()
1190+
dstBuf.Reset()
1191+
dstWriter.Reset(dstBuf)
11721192
io.Copy(dst, src)
11731193
}
11741194
}

0 commit comments

Comments
 (0)