]> Cypherpunks repositories - gostls13.git/commitdiff
bufio: in Reader.WriteTo, try to use target's ReaderFrom
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 27 Feb 2014 18:48:36 +0000 (10:48 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 27 Feb 2014 18:48:36 +0000 (10:48 -0800)
This is the simple half of https://golang.org/cl/53560043/ with
a new benchmark. pongad is in the C+A files already.

benchmark                         old ns/op     new ns/op     delta
BenchmarkReaderWriteToOptimal     2054          825           -59.83%

Update #6373

LGTM=iant, gri
R=golang-codereviews, iant, gri
CC=golang-codereviews
https://golang.org/cl/69220046

src/pkg/bufio/bufio.go
src/pkg/bufio/bufio_test.go

index d1ff3c9edc16dead49f6d860c71a1a55dc23b192..ef7447191549472de6bf181ed61bfa3b34ac25e2 100644 (file)
@@ -410,6 +410,12 @@ func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
                return n, err
        }
 
+       if w, ok := w.(io.ReaderFrom); ok {
+               m, err := w.ReadFrom(b.rd)
+               n += m
+               return n, err
+       }
+
        for b.fill(); b.r < b.w; b.fill() {
                m, err := b.writeBuf(w)
                n += m
index 3c86857e107c20be9b9120055f92afa031fd24f1..e48f5f89d9192b9bd95170ba3996771cfc9b6312 100644 (file)
@@ -1094,20 +1094,12 @@ func TestWriterReset(t *testing.T) {
 
 // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
 type onlyReader struct {
-       r io.Reader
-}
-
-func (r onlyReader) Read(b []byte) (int, error) {
-       return r.r.Read(b)
+       io.Reader
 }
 
 // An onlyWriter only implements io.Writer, no matter what other methods the underlying implementation may have.
 type onlyWriter struct {
-       w io.Writer
-}
-
-func (w onlyWriter) Write(b []byte) (int, error) {
-       return w.w.Write(b)
+       io.Writer
 }
 
 func BenchmarkReaderCopyOptimal(b *testing.B) {
@@ -1152,6 +1144,27 @@ func BenchmarkReaderCopyNoWriteTo(b *testing.B) {
        }
 }
 
+func BenchmarkReaderWriteToOptimal(b *testing.B) {
+       const bufSize = 16 << 10
+       buf := make([]byte, bufSize)
+       r := bytes.NewReader(buf)
+       srcReader := NewReaderSize(onlyReader{r}, 1<<10)
+       if _, ok := ioutil.Discard.(io.ReaderFrom); !ok {
+               b.Fatal("ioutil.Discard doesn't support ReaderFrom")
+       }
+       for i := 0; i < b.N; i++ {
+               r.Seek(0, 0)
+               srcReader.Reset(onlyReader{r})
+               n, err := srcReader.WriteTo(ioutil.Discard)
+               if err != nil {
+                       b.Fatal(err)
+               }
+               if n != bufSize {
+                       b.Fatalf("n = %d; want %d", n, bufSize)
+               }
+       }
+}
+
 func BenchmarkWriterCopyOptimal(b *testing.B) {
        // Optimal case is where the underlying writer implements io.ReaderFrom
        srcBuf := bytes.NewBuffer(make([]byte, 8192))