Created
July 4, 2018 05:53
-
-
Save anvinjain/92c1c48848f59ad494f98d90f752a7fd to your computer and use it in GitHub Desktop.
Golang Byte Array creation: append vs bytes.Join Benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"testing" | |
"bytes" | |
) | |
func TestBytesAppendIsEquivalentToJoin(t *testing.T) { | |
prefix := []byte("announce") | |
sep := "/" | |
peerType := []byte("s") | |
type serializedPeer []byte | |
pk := serializedPeer("jackandjill") | |
ihRaw := []byte("helloworld0123456789") | |
type InfoHash [20]byte | |
infoHashFromBytes := func(b []byte) InfoHash { | |
if len(b) != 20 { | |
panic("infohash must be 20 bytes") | |
} | |
var buf [20]byte | |
copy(buf[:], b) | |
return InfoHash(buf) | |
} | |
ih := infoHashFromBytes(ihRaw) | |
data:= &byteArrayParts{ | |
sep: []byte(sep), | |
p1: prefix, | |
p2: ih[:], | |
p3: peerType, | |
p4: pk, | |
} | |
k1 := generateByteArrayUsingAppend(data) | |
k2 := generateByteArrayUsingJoin(data) | |
if bytes.Compare(k1, k2) != 0 { | |
t.Fatal("both keys are not equal") | |
} | |
} | |
func BenchmarkByteAppend(b *testing.B) { | |
runByteArrayBenchmark(b, generateByteArrayUsingAppend) | |
} | |
func BenchmarkByteJoin(b *testing.B) { | |
runByteArrayBenchmark(b, generateByteArrayUsingJoin) | |
} | |
type byteArrayParts struct { | |
sep []byte | |
p1 []byte | |
p2 []byte | |
p3 []byte | |
p4 []byte | |
} | |
func generateByteArrayUsingAppend(data *byteArrayParts) []byte { | |
k := make([]byte, 0, len(data.sep) * 3 + len(data.p1) + len(data.p2) + len(data.p3) + len(data.p4)) | |
k = append(k, data.p1...) | |
k = append(k, data.sep...) | |
k = append(k, data.p2...) | |
k = append(k, data.sep...) | |
k = append(k, data.p3...) | |
k = append(k, data.sep...) | |
k = append(k, data.p4...) | |
return k | |
} | |
func generateByteArrayUsingJoin(data *byteArrayParts) []byte { | |
k := bytes.Join([][]byte{ | |
data.p1, | |
data.p2, | |
data.p3, | |
data.p4, | |
}, []byte(data.sep)) | |
return k | |
} | |
func runByteArrayBenchmark(b *testing.B, ef func(data *byteArrayParts) []byte) { | |
data := &byteArrayParts{ | |
sep: []byte("/"), | |
p1: []byte("announce"), | |
p2: []byte("helloworld0123456789"), | |
p3: []byte("s"), | |
p4: []byte("jackandjill"), | |
} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
ret := ef(data) | |
if len(ret) == 0 { | |
b.Fatal("empty byte array received") | |
} | |
} | |
b.StopTimer() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
goos: darwin
goarch: amd64
pkg: learning_go
20000000 61.5 ns/op #BenchmarkByteAppend
20000000 76.4 ns/op #BenchmarkByteJoin
PASS
BenchmarkByteJoin is 24% slower on my local setup.