]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: make integers encoding faster
authorAlberto Donizetti <alb.donizetti@gmail.com>
Fri, 17 Mar 2017 17:42:58 +0000 (18:42 +0100)
committerRob Pike <r@golang.org>
Fri, 17 Mar 2017 20:28:23 +0000 (20:28 +0000)
name                old time/op  new time/op  delta
EncodeInt32Slice-4  14.6µs ± 2%  12.2µs ± 1%  -16.65%  (p=0.000 n=19+18)

Change-Id: I078a171f1633ff81d7e3f981dc9a398309ecb2c0
Reviewed-on: https://go-review.googlesource.com/38269
Reviewed-by: Rob Pike <r@golang.org>
src/encoding/gob/encode.go
src/encoding/gob/timing_test.go

index 50cd6adb463c40da17d63419fa0842d468a68b5c..d67153da90242ffa0a70ada3edad6da1a5c5a035 100644 (file)
@@ -8,7 +8,9 @@ package gob
 
 import (
        "encoding"
+       "encoding/binary"
        "math"
+       "math/bits"
        "reflect"
        "sync"
 )
@@ -107,14 +109,12 @@ func (state *encoderState) encodeUint(x uint64) {
                state.b.WriteByte(uint8(x))
                return
        }
-       i := uint64Size
-       for x > 0 {
-               state.buf[i] = uint8(x)
-               x >>= 8
-               i--
-       }
-       state.buf[i] = uint8(i - uint64Size) // = loop count, negated
-       state.b.Write(state.buf[i : uint64Size+1])
+
+       binary.BigEndian.PutUint64(state.buf[1:], x)
+       bc := bits.LeadingZeros64(x) >> 3      // 8 - bytelen(x)
+       state.buf[bc] = uint8(bc - uint64Size) // and then we subtract 8 to get -bytelen(x)
+
+       state.b.Write(state.buf[bc : uint64Size+1])
 }
 
 // encodeInt writes an encoded signed integer to state.w.
index 424b7e6ea8e7a2b91dd3f105f7bb39cc9ceaaf16..a7e7e683cc38734025dfe0cb20e8f61996f2eb3e 100644 (file)
@@ -171,7 +171,7 @@ func BenchmarkEncodeInt32Slice(b *testing.B) {
        enc := NewEncoder(&buf)
        a := make([]int32, 1000)
        for i := range a {
-               a[i] = 1234
+               a[i] = int32(i * 100)
        }
        b.ResetTimer()
        for i := 0; i < b.N; i++ {