diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2011-05-26 09:01:05 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2011-05-26 09:01:05 -0700 |
| commit | 3648a03b3a1ae7c73f1853a8413c6ce4d64ade2f (patch) | |
| tree | 44439fcfd5711e5f9e35847198ec8bc9f6170606 /src/pkg/encoding/binary/binary.go | |
| parent | c0decc35ae031333a61b816670d668f01f594dd8 (diff) | |
| download | go-3648a03b3a1ae7c73f1853a8413c6ce4d64ade2f.tar.xz | |
encoding/binary: add a non-reflect fast path for Read
before/after:
binary.BenchmarkRead 200000 10860 ns/op
binary.BenchmarkRead 500000 2846 ns/op
R=rsc
CC=golang-dev
https://golang.org/cl/4547062
Diffstat (limited to 'src/pkg/encoding/binary/binary.go')
| -rw-r--r-- | src/pkg/encoding/binary/binary.go | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/pkg/encoding/binary/binary.go b/src/pkg/encoding/binary/binary.go index a01d0e0246..d0185ebb71 100644 --- a/src/pkg/encoding/binary/binary.go +++ b/src/pkg/encoding/binary/binary.go @@ -125,6 +125,54 @@ func (bigEndian) GoString() string { return "binary.BigEndian" } // Bytes read from r are decoded using the specified byte order // and written to successive fields of the data. func Read(r io.Reader, order ByteOrder, data interface{}) os.Error { + // Fast path for basic types + var n int + switch data.(type) { + case *int8: + n = 1 + case *uint8: + n = 1 + case *int16: + n = 2 + case *uint16: + n = 2 + case *int32: + n = 4 + case *uint32: + n = 4 + case *int64: + n = 8 + case *uint64: + n = 8 + } + if n != 0 { + var buf [8]byte + bs := buf[:n] + if _, err := io.ReadFull(r, bs); err != nil { + return err + } + switch v := data.(type) { + case *int8: + *v = int8(buf[0]) + case *uint8: + *v = buf[0] + case *int16: + *v = int16(order.Uint16(bs)) + case *uint16: + *v = order.Uint16(bs) + case *int32: + *v = int32(order.Uint32(bs)) + case *uint32: + *v = order.Uint32(bs) + case *int64: + *v = int64(order.Uint64(bs)) + case *uint64: + *v = order.Uint64(bs) + } + return nil + } + + // Fallback to reflect-based. var v reflect.Value switch d := reflect.ValueOf(data); d.Kind() { case reflect.Ptr: |
