As research
goos: linux goarch: amd64 pkg: fsm/finder cpu: Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz BenchmarkBinWrite-4 13289688 185.1 ns/op 128 B/op 4 allocs/op BenchmarkAtoi-4 53319615 44.95 ns/op 7 B/op 0 allocs/op BenchmarkEncoder-4 40339908 57.88 ns/op 15 B/op 1 allocs/op BenchmarkEncoderHex-4 21469190 118.1 ns/op 31 B/op 2 allocs/op PASS ok fsm/finder 10.142s
// // Package for converting integers to byte array and vice versa. // BigEndian byte order is used. // package icoder import ( "bytes" "encoding/binary" "errors" "reflect" ) const sizeOfInt64 int = 8 const sizeOfInt32 int = 4 const sizeOfInt16 int = 2 // Standard method for comparison func BinWrite(v interface{}) ([]byte, error) { buffer := new(bytes.Buffer) err := binary.Write(buffer, binary.BigEndian, v) return buffer.Bytes(), err } // Converts an integer or an integer reference to an appropriately // sized byte array. If a non-integer number is passed, // the function returns an error func Encoder(intv interface{}) ([]byte, error) { const sizeOfInt64 int = 8 const bitsPerByte int = 8 var err error var uintv uint64 buffer := make([]byte, sizeOfInt64) v := reflect.ValueOf(intv) i := reflect.Indirect(v) t := i.Type() kind := t.Kind() switch kind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: uintv = uint64(i.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: uintv = uint64(i.Uint()) default: return buffer, errors.New("type is not int or uint kind") } vSize := t.Bits() / bitsPerByte binary.BigEndian.PutUint64(buffer, uintv) return buffer[sizeOfInt64 - vSize:], err } // Converts a byte array to an integer passed by reference func Decoder(b []byte, s interface{}) error { var err error var uintv uint64 lenb := len(b) buffer := make([]byte, sizeOfInt64 - lenb) buffer = append(buffer, b...) uintv = binary.BigEndian.Uint64(buffer) v := reflect.ValueOf(s) i := reflect.Indirect(v) t := i.Type() kind := t.Kind() switch kind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: i.SetInt(int64(uintv)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: i.SetUint(uint64(uintv)) default: return errors.New("type is not int or uint kind") } return err } // Converts an integer to a byte array func EncoderU64(s uint64) []byte { buffer := make([]byte, sizeOfInt64) binary.BigEndian.PutUint64(buffer, s) return buffer } // Converts an integer to a byte array func EncoderU32(s uint32) []byte { buffer := make([]byte, sizeOfInt32) binary.BigEndian.PutUint32(buffer, s) return buffer } // Converts an integer to a byte array func EncoderU16(s uint16) []byte { buffer := make([]byte, sizeOfInt16) binary.BigEndian.PutUint16(buffer, s) return buffer } // Converts a byte array to an integer. func DecoderU64(b []byte) uint64 { return binary.BigEndian.Uint64(b) } // Converts a byte array to an integer. func DecoderU32(b []byte) uint32 { return binary.BigEndian.Uint32(b) } // Converts a byte array to an integer. func DecoderU16(b []byte) uint16 { return binary.BigEndian.Uint16(b) } //EOF
// // $Id$ // package icoder import ( "encoding/hex" "testing" "strconv" "github.com/stretchr/testify/assert" ) func TestEncoderDecoder64(t *testing.T) { i := uint64(12345678901234567898) b, err := Encoder(i) if err != nil { t.Fatal(err) } var o uint64 err = Decoder(b, &o) if err != nil { t.Fatal(err) } assert.Equal(t, i, o, nil) } func TestEncoderDecoder32(t *testing.T) { i := uint32(1234567890) b, err := Encoder(i) if err != nil { t.Fatal(err) } var o uint32 err = Decoder(b, &o) if err != nil { t.Fatal(err) } assert.Equal(t, i, o, nil) } func TestEncoderDecoderU64(t *testing.T) { i := uint64(1234567890123456789) b := EncoderU64(i) o := DecoderU64(b) assert.Equal(t, i, o, nil) } func TestEncoderDecoderU32(t *testing.T) { i := uint32(1234567890) b := EncoderU32(i) o := DecoderU32(b) assert.Equal(t, i, o, nil) } func TestEncoderDecoderU16(t *testing.T) { i := uint16(12345) b := EncoderU16(i) o := DecoderU16(b) assert.Equal(t, i, o, nil) } func BenchmarkBinWrite(b *testing.B) { for i := 0; i < b.N; i++ { i64 := int64(i) _, err := BinWrite(&i64) if err != nil { b.Error(err) } } } func BenchmarkAtoi(b *testing.B) { for i := 0; i < b.N; i++ { _ = strconv.Itoa(i) } } func BenchmarkEncoder(b *testing.B) { for i := 0; i < b.N; i++ { _, err := Encoder(i) if err != nil { b.Error(err) } } } func BenchmarkEncoderHex(b *testing.B) { for i := 0; i < b.N; i++ { bytes, err := Encoder(i) if err != nil { b.Error(err) } _ = hex.EncodeToString(bytes) } } //EOF