bytes_unsafe_test.go 1.7 KB

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