Skip to content

Commit

Permalink
Inline everything into single switch
Browse files Browse the repository at this point in the history
name                                     old time/op    new time/op    delta
Encode/int32-8                              249ns ± 0%     132ns ± 0%  -46.99%  (p=1.000 n=1+1)
Encode/struct_wrapping_int64-8              562ns ± 0%     413ns ± 0%  -26.51%  (p=1.000 n=1+1)
Encode/string-8                             335ns ± 0%     347ns ± 0%   +3.58%  (p=1.000 n=1+1)
Encode/float32-8                            131ns ± 0%     137ns ± 0%   +4.58%  (p=1.000 n=1+1)
Encode/time.Time-8                          626ns ± 0%     620ns ± 0%   -0.96%  (p=1.000 n=1+1)
Encode/int-8                                246ns ± 0%     149ns ± 0%  -39.43%  (p=1.000 n=1+1)
Encode/int8-8                               212ns ± 0%     107ns ± 0%  -49.53%  (p=1.000 n=1+1)
Encode/uint-8                               133ns ± 0%      79ns ± 0%  -40.30%  (p=1.000 n=1+1)
Encode/uint16-8                             131ns ± 0%      65ns ± 0%  -50.69%  (p=1.000 n=1+1)
Encode/uint32-8                             125ns ± 0%      69ns ± 0%  -45.04%  (p=1.000 n=1+1)
Encode/bool-8                              57.5ns ± 0%    28.9ns ± 0%  -49.74%  (p=1.000 n=1+1)
Encode/uint8-8                              183ns ± 0%      92ns ± 0%  -49.78%  (p=1.000 n=1+1)
Encode/int16-8                              224ns ± 0%     131ns ± 0%  -41.52%  (p=1.000 n=1+1)
Encode/int64-8                              242ns ± 0%     148ns ± 0%  -38.84%  (p=1.000 n=1+1)
Encode/uint64-8                             130ns ± 0%      79ns ± 0%  -39.00%  (p=1.000 n=1+1)
Encode/float64-8                            139ns ± 0%     148ns ± 0%   +6.47%  (p=1.000 n=1+1)
Encode_parallel/float32-8                  32.1ns ± 0%    32.7ns ± 0%   +1.87%  (p=1.000 n=1+1)
Encode_parallel/time.Time-8                 177ns ± 0%     169ns ± 0%   -4.52%  (p=1.000 n=1+1)
Encode_parallel/int-8                      73.0ns ± 0%    38.3ns ± 0%  -47.53%  (p=1.000 n=1+1)
Encode_parallel/int8-8                     56.8ns ± 0%    26.7ns ± 0%  -52.99%  (p=1.000 n=1+1)
Encode_parallel/uint-8                     41.5ns ± 0%    21.7ns ± 0%  -47.71%  (p=1.000 n=1+1)
Encode_parallel/uint16-8                   37.6ns ± 0%    16.6ns ± 0%  -55.85%  (p=1.000 n=1+1)
Encode_parallel/uint32-8                   36.5ns ± 0%    17.6ns ± 0%  -51.78%  (p=1.000 n=1+1)
Encode_parallel/bool-8                     16.0ns ± 0%     7.4ns ± 0%  -53.81%  (p=1.000 n=1+1)
Encode_parallel/uint8-8                    54.7ns ± 0%    23.0ns ± 0%  -57.95%  (p=1.000 n=1+1)
Encode_parallel/int16-8                    59.4ns ± 0%    31.1ns ± 0%  -47.64%  (p=1.000 n=1+1)
Encode_parallel/int64-8                    71.4ns ± 0%    38.4ns ± 0%  -46.22%  (p=1.000 n=1+1)
Encode_parallel/uint64-8                   40.1ns ± 0%    20.9ns ± 0%  -47.88%  (p=1.000 n=1+1)
Encode_parallel/float64-8                  37.0ns ± 0%    39.8ns ± 0%   +7.57%  (p=1.000 n=1+1)
Encode_parallel/int32-8                    70.5ns ± 0%    33.1ns ± 0%  -53.05%  (p=1.000 n=1+1)
Encode_parallel/struct_wrapping_int64-8     173ns ± 0%     122ns ± 0%  -29.48%  (p=1.000 n=1+1)
Encode_parallel/string-8                   90.6ns ± 0%    97.5ns ± 0%   +7.62%  (p=1.000 n=1+1)
  • Loading branch information
nochso committed Jul 30, 2017
1 parent 2d5ad42 commit ab2cdb7
Showing 1 changed file with 42 additions and 63 deletions.
105 changes: 42 additions & 63 deletions bytesort.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,91 +48,70 @@ type Encoder interface {
// string (case-sensitive)
// time.Time (normalised to UTC)
func Encode(v interface{}) (b []byte, err error) {
switch v.(type) {
switch vv := v.(type) {
case string:
b = []byte(v.(string))
b = []byte(vv)
// Special case for empty strings because empty bucket names are not
// allowed. Use a zero byte to represent an empty string.
if len(b) == 0 {
b = append(b, 0)
}
return
case time.Time:
return encodeTime(v.(time.Time))
return encodeTime(vv)
case float64:
return encodeFloat64(v.(float64)), nil
return encodeFloat64(vv), nil
case float32:
return encodeFloat32(v.(float32)), nil
case Encoder:
return v.(Encoder).EncodeSortable()
}

b, err = encodeInt(v)
if err != nil {
return
}
return
}

func encodeInt(data interface{}) ([]byte, error) {
n := intDataSize(data)
if n == 0 {
return nil, fmt.Errorf("bytesort.Encode: unsupported type %T", data)
}
bs := make([]byte, n)
switch v := data.(type) {
return encodeFloat32(vv), nil
case bool:
if v {
bs[0] = 1
} else {
bs[0] = 0
if vv {
return []byte{1}, nil
}
return []byte{0}, nil
case int8:
bs[0] = byte(v)
return []byte{byte(vv) ^ 0x80}, nil
case uint8:
bs[0] = v
return []byte{vv}, nil
case int16:
binary.BigEndian.PutUint16(bs, uint16(v))
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, uint16(vv))
b[0] ^= 0x80
return b, nil
case uint16:
binary.BigEndian.PutUint16(bs, v)
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, vv)
return b, nil
case int32:
binary.BigEndian.PutUint32(bs, uint32(v))
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, uint32(vv))
b[0] ^= 0x80
return b, nil
case uint32:
binary.BigEndian.PutUint32(bs, v)
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, vv)
return b, nil
case int64:
binary.BigEndian.PutUint64(bs, uint64(v))
case int:
binary.BigEndian.PutUint64(bs, uint64(int64(v)))
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(vv))
b[0] ^= 0x80
return b, nil
case uint64:
binary.BigEndian.PutUint64(bs, v)
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, vv)
return b, nil
case int:
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(vv))
b[0] ^= 0x80
return b, nil
case uint:
binary.BigEndian.PutUint64(bs, uint64(v))
}
switch data.(type) {
case int64, int32, int16, int8, int:
// The order is almost correct, however ascending positive numbers are
// currently before ascending negative numbers. Flip the first bit of
// the two's complement: both ranges switch places, resulting in
// consecutively ascending sort order.
bs[0] ^= 0x80
}
return bs, nil
}

// intDataSize returns the size of the data required to represent the data when encoded.
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
func intDataSize(data interface{}) int {
switch data.(type) {
case bool, int8, uint8:
return 1
case int16, uint16:
return 2
case int32, uint32:
return 4
case int64, uint64, int, uint:
return 8
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(vv))
return b, nil
case Encoder:
return vv.EncodeSortable()
}
return 0
return nil, fmt.Errorf("bytesort.Encode: unsupported type %T", v)
}

// http://stereopsis.com/radix.html
Expand Down

0 comments on commit ab2cdb7

Please sign in to comment.