]> Cypherpunks repositories - gostls13.git/commitdiff
gob: eliminate two more allocations in decode.
authorRob Pike <r@golang.org>
Thu, 17 Mar 2011 17:47:42 +0000 (10:47 -0700)
committerRob Pike <r@golang.org>
Thu, 17 Mar 2011 17:47:42 +0000 (10:47 -0700)
- just an oversight; we were reallocating a buffer.
- use unsafe to avoid allocating storage for a string twice.

R=rsc
CC=golang-dev
https://golang.org/cl/4290056

src/pkg/gob/decode.go

index f77504d871d45e3d1bd8d1b9102036fb4cdf5463..f8159d4ea32357fd20a69524ed9a89b2593eedc5 100644 (file)
@@ -41,11 +41,11 @@ func (dec *Decoder) newDecoderState(buf *bytes.Buffer) *decoderState {
        if d == nil {
                d = new(decoderState)
                d.dec = dec
+               d.buf = make([]byte, uint64Size)
        } else {
                dec.freeList = d.next
        }
        d.b = buf
-       d.buf = make([]byte, uint64Size)
        return d
 }
 
@@ -412,7 +412,14 @@ func decString(i *decInstr, state *decoderState, p unsafe.Pointer) {
        }
        b := make([]byte, state.decodeUint())
        state.b.Read(b)
-       *(*string)(p) = string(b)
+       // It would be a shame to do the obvious thing here,
+       //      *(*string)(p) = string(b)
+       // because we've already allocated the storage and this would
+       // allocate again and copy.  So we do this ugly hack, which is even
+       // even more unsafe than it looks as it depends the memory
+       // representation of a string matching the beginning of the memory
+       // representation of a byte slice (a byte slice is longer).
+       *(*string)(p) = *(*string)(unsafe.Pointer(&b))
 }
 
 // ignoreUint8Array skips over the data for a byte slice value with no destination.