-
Notifications
You must be signed in to change notification settings - Fork 435
/
bytes_unsafe_test.go
69 lines (58 loc) · 1.7 KB
/
bytes_unsafe_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// +build !appengine,!appenginevm
package jsonparser
import (
"reflect"
"strings"
"testing"
"unsafe"
)
var (
// short string/[]byte sequences, as the difference between these
// three methods is a constant overhead
benchmarkString = "0123456789x"
benchmarkBytes = []byte("0123456789y")
)
func bytesEqualStrSafe(abytes []byte, bstr string) bool {
return bstr == string(abytes)
}
func bytesEqualStrUnsafeSlower(abytes *[]byte, bstr string) bool {
aslicehdr := (*reflect.SliceHeader)(unsafe.Pointer(abytes))
astrhdr := reflect.StringHeader{Data: aslicehdr.Data, Len: aslicehdr.Len}
return *(*string)(unsafe.Pointer(&astrhdr)) == bstr
}
func TestEqual(t *testing.T) {
if !equalStr(&[]byte{}, "") {
t.Errorf(`equalStr("", ""): expected true, obtained false`)
return
}
longstr := strings.Repeat("a", 1000)
for i := 0; i < len(longstr); i++ {
s1, s2 := longstr[:i]+"1", longstr[:i]+"2"
b1 := []byte(s1)
if !equalStr(&b1, s1) {
t.Errorf(`equalStr("a"*%d + "1", "a"*%d + "1"): expected true, obtained false`, i, i)
break
}
if equalStr(&b1, s2) {
t.Errorf(`equalStr("a"*%d + "1", "a"*%d + "2"): expected false, obtained true`, i, i)
break
}
}
}
func BenchmarkEqualStr(b *testing.B) {
for i := 0; i < b.N; i++ {
equalStr(&benchmarkBytes, benchmarkString)
}
}
// Alternative implementation without using unsafe
func BenchmarkBytesEqualStrSafe(b *testing.B) {
for i := 0; i < b.N; i++ {
bytesEqualStrSafe(benchmarkBytes, benchmarkString)
}
}
// Alternative implementation using unsafe, but that is slower than the current implementation
func BenchmarkBytesEqualStrUnsafeSlower(b *testing.B) {
for i := 0; i < b.N; i++ {
bytesEqualStrUnsafeSlower(&benchmarkBytes, benchmarkString)
}
}