diff --git a/binary/protobuf.go b/binary/protobuf.go index ba520612..c36a7e92 100644 --- a/binary/protobuf.go +++ b/binary/protobuf.go @@ -72,31 +72,17 @@ func (en *encoder) uvarint(v uint64) { } func (en *encoder) svarint(v int64) { - if v >= 0 { - en.uvarint(uint64(v) << 1) - } else { - en.uvarint(^uint64(v << 1)) - } + en.uvarint(uint64(v)<<1 ^ uint64(v>>63)) } func (en *encoder) u32(v uint32) { - var b [4]byte - b[0] = byte(v) - b[1] = byte(v >> 8) - b[2] = byte(v >> 16) - b[3] = byte(v >> 24) + var b [8]byte + binary.LittleEndian.PutUint32(b[:], v) _, _ = en.Write(b[:]) } func (en *encoder) u64(v uint64) { var b [8]byte - b[0] = byte(v) - b[1] = byte(v >> 8) - b[2] = byte(v >> 16) - b[3] = byte(v >> 24) - b[4] = byte(v >> 32) - b[5] = byte(v >> 40) - b[6] = byte(v >> 48) - b[7] = byte(v >> 56) + binary.LittleEndian.PutUint64(b[:], v) _, _ = en.Write(b[:]) } diff --git a/binary/protobuf_test.go b/binary/protobuf_test.go index d919e707..844bab50 100644 --- a/binary/protobuf_test.go +++ b/binary/protobuf_test.go @@ -13,6 +13,14 @@ func benchEncoderUvarint(b *testing.B, v uint64) { } } +func benchEncoderSvarint(b *testing.B, v int64) { + e := encoder{} + for i := 0; i < b.N; i++ { + e.Reset() + e.svarint(v) + } +} + func Benchmark_encoder_uvarint(b *testing.B) { b.Run("short", func(b *testing.B) { benchEncoderUvarint(b, uint64(1)) @@ -24,3 +32,15 @@ func Benchmark_encoder_uvarint(b *testing.B) { benchEncoderUvarint(b, math.MaxUint64) }) } + +func Benchmark_encoder_svarint(b *testing.B) { + b.Run("short", func(b *testing.B) { + benchEncoderSvarint(b, int64(1)) + }) + b.Run("medium", func(b *testing.B) { + benchEncoderSvarint(b, int64(114514)) + }) + b.Run("large", func(b *testing.B) { + benchEncoderSvarint(b, math.MaxInt64) + }) +}