diff options
| author | Alex Gaynor <alex.gaynor@gmail.com> | 2020-04-27 23:10:23 +0000 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2020-04-28 00:53:32 +0000 |
| commit | c2e0f01598fbc17d2f960fe93c5bcb057203b75d (patch) | |
| tree | 544402aa7986b8c1fcf7e0957e663f9932a338fd /src/bufio/bufio_test.go | |
| parent | 42c48998aada0df10279650d04a018c83cbfa518 (diff) | |
| download | go-c2e0f01598fbc17d2f960fe93c5bcb057203b75d.tar.xz | |
bufio: optimize bufio.Reader.ReadString to avoid an allocation and copy
name old time/op new time/op delta
ReaderReadString-4 226ns ±12% 161ns ±11% -28.76% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
ReaderReadString-4 288B ± 0% 144B ± 0% -50.00% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
ReaderReadString-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
Change-Id: I77f330b8340c2bfbfff1f6f1000170b65953a200
GitHub-Last-Rev: 65d65302a7b80504b4d37b81a3843fe1439e638a
GitHub-Pull-Request: golang/go#34706
Reviewed-on: https://go-review.googlesource.com/c/go/+/199257
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/bufio/bufio_test.go')
| -rw-r--r-- | src/bufio/bufio_test.go | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go index 4c4522c660..cb68f3ba23 100644 --- a/src/bufio/bufio_test.go +++ b/src/bufio/bufio_test.go @@ -535,6 +535,23 @@ func TestReadWriteRune(t *testing.T) { } } +func TestReadStringAllocs(t *testing.T) { + r := strings.NewReader(" foo foo 42 42 42 42 42 42 42 42 4.2 4.2 4.2 4.2\n") + buf := NewReader(r) + allocs := testing.AllocsPerRun(100, func() { + r.Seek(0, io.SeekStart) + buf.Reset(r) + + _, err := buf.ReadString('\n') + if err != nil { + t.Fatal(err) + } + }) + if allocs != 1 { + t.Errorf("Unexpected number of allocations, got %f, want 1", allocs) + } +} + func TestWriter(t *testing.T) { var data [8192]byte @@ -1644,6 +1661,21 @@ func BenchmarkReaderWriteToOptimal(b *testing.B) { } } +func BenchmarkReaderReadString(b *testing.B) { + r := strings.NewReader(" foo foo 42 42 42 42 42 42 42 42 4.2 4.2 4.2 4.2\n") + buf := NewReader(r) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + r.Seek(0, io.SeekStart) + buf.Reset(r) + + _, err := buf.ReadString('\n') + if err != nil { + b.Fatal(err) + } + } +} + func BenchmarkWriterCopyOptimal(b *testing.B) { // Optimal case is where the underlying writer implements io.ReaderFrom srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
