File: bytes_unsafe_test.go

package info (click to toggle)
golang-github-buger-jsonparser 0.0~git20170705.0.9addec9-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 636 kB
  • sloc: makefile: 29
file content (69 lines) | stat: -rw-r--r-- 1,740 bytes parent folder | download | duplicates (3)
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)
	}
}