Skip to content

Commit

Permalink
Merge pull request cosmos#26 from odeke-em/improve-reverse-bytes+tests
Browse files Browse the repository at this point in the history
hd: optimize ReverseBytes + add tests
  • Loading branch information
ethanfrey authored Jul 28, 2017
2 parents bf355d1 + ae9c5b1 commit f2c8815
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
17 changes: 14 additions & 3 deletions hd/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,20 @@ func CalcSha512(buf []byte) []byte {
}

func ReverseBytes(buf []byte) []byte {
res := []byte{}
for i := len(buf) - 1; i >= 0; i-- {
res = append(res, buf[i])
var res []byte
if len(buf) == 0 {
return res
}

// Walk till mid-way, swapping bytes from each end:
// b[i] and b[len-i-1]
blen := len(buf)
res = make([]byte, blen)
mid := blen / 2
for left := 0; left <= mid; left++ {
right := blen - left - 1
res[left] = buf[right]
res[right] = buf[left]
}
return res
}
53 changes: 53 additions & 0 deletions hd/hd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ func TestHDToAddr(t *testing.T) {
}
}

func TestReverseBytes(t *testing.T) {
tests := [...]struct {
v []byte
want []byte
}{
{[]byte(""), []byte("")},
{nil, nil},
{[]byte("Tendermint"), []byte("tnimredneT")},
{[]byte("T"), []byte("T")},
{[]byte("Te"), []byte("eT")},
}

for i, tt := range tests {
got := ReverseBytes(tt.v)
if !bytes.Equal(got, tt.want) {
t.Errorf("#%d:\ngot= (%x)\nwant=(%x)", i, got, tt.want)
}
}
}

func ifExit(err error, n int) {
if err != nil {
fmt.Println(n, err)
Expand Down Expand Up @@ -187,3 +207,36 @@ func tylerSmith(seed []byte) ([]byte, []byte, []byte) {
pub := k.PublicKey().Key
return masterKey.Key, priv, pub
}

// Benchmarks

var revBytesCases = [][]byte{
nil,
[]byte(""),

[]byte("12"),

// 16byte case
[]byte("abcdefghijklmnop"),

// 32byte case
[]byte("abcdefghijklmnopqrstuvwxyz123456"),

// 64byte case
[]byte("abcdefghijklmnopqrstuvwxyz123456abcdefghijklmnopqrstuvwxyz123456"),
}

func BenchmarkReverseBytes(b *testing.B) {
var sink []byte
for i := 0; i < b.N; i++ {
for _, tt := range revBytesCases {
sink = ReverseBytes(tt)
}
}
b.ReportAllocs()

// sink is necessary to ensure if the compiler tries
// to smart, that it won't optimize away the benchmarks.
if sink != nil {
}
}

0 comments on commit f2c8815

Please sign in to comment.