aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/encoding/binary/binary.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-05-26 09:01:05 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-05-26 09:01:05 -0700
commit3648a03b3a1ae7c73f1853a8413c6ce4d64ade2f (patch)
tree44439fcfd5711e5f9e35847198ec8bc9f6170606 /src/pkg/encoding/binary/binary.go
parentc0decc35ae031333a61b816670d668f01f594dd8 (diff)
downloadgo-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.go48
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: