github.com/coyove/nj@v0.0.0-20221110084952-c7f8db1065c3/tests/gobench/bytes_test.go (about)

     1  package bench
     2  
     3  import (
     4  	"bytes"
     5  	"math/rand"
     6  	"sort"
     7  	"strconv"
     8  	"testing"
     9  	"time"
    10  	"unsafe"
    11  )
    12  
    13  func concatBytes(a, b []byte) []byte {
    14  	c := make([]byte, len(a)+len(b))
    15  	copy(c, a)
    16  	copy(c[len(a):], b)
    17  	return c
    18  }
    19  
    20  func bytesString(a []byte) string {
    21  	return *(*string)(unsafe.Pointer(&a))
    22  }
    23  
    24  func bytesString2(a []byte) string {
    25  	return string(a)
    26  }
    27  
    28  func TestBytesInterface(t *testing.T) {
    29  	a := []byte("zzz")
    30  	m := map[interface{}]int{}
    31  	m[bytesString(a)] = 99
    32  	a[1] = 'a'
    33  	t.Log(m)
    34  }
    35  
    36  var dummies = []string{strconv.Itoa(rand.Int()), strconv.Itoa(rand.Int()), strconv.Itoa(rand.Int()), strconv.Itoa(rand.Int())}
    37  
    38  func BenchmarkBytes(b *testing.B) {
    39  	v1, v2 := make([]byte, 18), make([]byte, 18)
    40  	rand.Read(v1)
    41  	rand.Read(v2)
    42  
    43  	for i := 0; i < b.N; i++ {
    44  		v3 := concatBytes(v1, v2)
    45  		if bytes.Equal(v3, nil) {
    46  			b.Fatal(1)
    47  		}
    48  	}
    49  }
    50  
    51  func BenchmarkString(b *testing.B) {
    52  	v1, v2 := dummies[rand.Intn(len(dummies))], dummies[rand.Intn(len(dummies))]
    53  	for i := 0; i < b.N; i++ {
    54  		v3 := v1 + v2
    55  		if v3 == "" {
    56  			b.Fatal(1)
    57  		}
    58  	}
    59  }
    60  
    61  func BenchmarkBytesReplace(b *testing.B) {
    62  	v1 := dummies[rand.Intn(len(dummies))]
    63  
    64  	for i := 0; i < b.N; i++ {
    65  		x := []byte(v1)
    66  		x[1] = 'z'
    67  		v3 := string(x)
    68  		if v3 == "" {
    69  			b.Fatal(1)
    70  		}
    71  	}
    72  }
    73  
    74  func BenchmarkStringReplace(b *testing.B) {
    75  	v1 := dummies[rand.Intn(len(dummies))]
    76  	for i := 0; i < b.N; i++ {
    77  		v3 := v1[:1] + "z" + v1[2:]
    78  		if v3 == "" {
    79  			b.Fatal(1)
    80  		}
    81  	}
    82  }
    83  
    84  type IntMap []uint64
    85  
    86  func (m IntMap) Get(k uint64) (v uint64, ok bool) {
    87  	offset := len(m) / 2
    88  	j := offset
    89  
    90  	if j > 0 && m[0] == k {
    91  		return m[offset], true
    92  	}
    93  
    94  	if j > 1 && m[1] == k {
    95  		return m[1+offset], true
    96  	}
    97  	//	return 0, false
    98  
    99  	for i := 2; i < j; {
   100  		h := int(uint(i+j) >> 1) // avoid overflow when computing h
   101  
   102  		k2 := &m[h]
   103  		if *k2 == k {
   104  			return *(*uint64)(unsafe.Pointer(uintptr(unsafe.Pointer(k2)) + uintptr(offset)*unsafe.Sizeof(uint64(0)))), true
   105  			// return m.values[h+offset], true
   106  		}
   107  
   108  		if *k2 < k {
   109  			i = h + 1
   110  		} else {
   111  			j = h
   112  		}
   113  	}
   114  
   115  	return 0, false
   116  }
   117  
   118  func (m *IntMap) Add(k uint64, v uint64) {
   119  	offset := len(*m) / 2
   120  	i, j := 0, offset
   121  
   122  	for i < j {
   123  		h := int(uint(i+j) >> 1) // avoid overflow when computing h
   124  		// i ≤ h < j
   125  		if (*m)[h] == k {
   126  			(*m)[h+offset] = v
   127  			return
   128  		}
   129  
   130  		if (*m)[h] < k {
   131  			i = h + 1 // preserves f(i-1) == false
   132  		} else {
   133  			j = h // preserves f(j) == true
   134  		}
   135  	}
   136  
   137  	*m = append(*m, 0, 0)
   138  	copy((*m)[i+offset+2:], (*m)[i+offset:])
   139  	(*m)[i+offset+1] = v
   140  	copy((*m)[i+1:], (*m)[i:i+offset])
   141  	(*m)[i] = k
   142  }
   143  
   144  type kvSwapper []uint64
   145  
   146  func (s kvSwapper) Len() int {
   147  	return len(s) / 2
   148  }
   149  
   150  func (s kvSwapper) Less(i, j int) bool {
   151  	return (s)[i] < (s)[j]
   152  }
   153  
   154  func (s kvSwapper) Swap(i, j int) {
   155  	(s)[i], (s)[j] = (s)[j], (s)[i]
   156  	i, j = i+len(s)/2, j+len(s)/2
   157  	(s)[i], (s)[j] = (s)[j], (s)[i]
   158  }
   159  
   160  func (m *IntMap) BatchSet(kv []uint64) {
   161  	*m = kv
   162  	sort.Sort(kvSwapper(*m))
   163  }
   164  
   165  var N = 16
   166  
   167  func TestMapBatch(t *testing.T) {
   168  	rand.Seed(time.Now().Unix())
   169  
   170  	m := IntMap{}
   171  	m2 := map[uint64]bool{}
   172  
   173  	args := make([]uint64, N*2)
   174  	for i := 0; i < N; i++ {
   175  		x := uint64(rand.Int())
   176  		m2[x] = true
   177  		args[i] = x
   178  		args[i+N] = x
   179  	}
   180  
   181  	m.BatchSet(args)
   182  
   183  	for k := range m2 {
   184  		if v, _ := m.Get(k); v != k {
   185  			t.Fatal(m)
   186  		}
   187  	}
   188  }
   189  
   190  func TestMapAdd(t *testing.T) {
   191  	m := IntMap{}
   192  	m2 := map[uint64]bool{}
   193  	for i := 0; i < N; i++ {
   194  		x := uint64(rand.Int())
   195  		m.Add(x, x)
   196  		m2[x] = true
   197  	}
   198  
   199  	for k := range m2 {
   200  		if v, _ := m.Get(k); v != k {
   201  			t.Fatal(m)
   202  		}
   203  	}
   204  }
   205  
   206  func BenchmarkNativeMapIndex(b *testing.B) {
   207  	b.StopTimer()
   208  	m := map[uint64]uint64{}
   209  	for i := 0; i < N; i++ {
   210  		x := uint64(rand.Int())
   211  		m[x] = x
   212  	}
   213  	b.StartTimer()
   214  
   215  	for i := 0; i < b.N; i++ {
   216  		if m[uint64(i)] == 999 {
   217  			b.Fatal(m)
   218  		}
   219  	}
   220  }
   221  
   222  func BenchmarkMapIndex(b *testing.B) {
   223  	b.StopTimer()
   224  	m := IntMap{}
   225  	for i := 0; i < N; i++ {
   226  		x := uint64(rand.Int())
   227  		m.Add(x, x)
   228  	}
   229  	b.StartTimer()
   230  
   231  	for i := 0; i < b.N; i++ {
   232  		if v, _ := m.Get(uint64(i)); v == 999 {
   233  			b.Fatal(m)
   234  		}
   235  	}
   236  
   237  	//b.Log(m)
   238  }
   239  
   240  func BenchmarkNativeMapAdd(b *testing.B) {
   241  	for i := 0; i < b.N; i++ {
   242  		m := map[uint64]uint64{}
   243  		for i := 0; i < N; i++ {
   244  			x := uint64(rand.Int())
   245  			m[x] = x
   246  		}
   247  	}
   248  }
   249  
   250  func BenchmarkMapAdd(b *testing.B) {
   251  	for i := 0; i < b.N; i++ {
   252  		m := IntMap{}
   253  		for i := 0; i < N; i++ {
   254  			x := uint64(rand.Int())
   255  			m.Add(x, x)
   256  		}
   257  	}
   258  }
   259  
   260  func BenchmarkMapBatch(b *testing.B) {
   261  	for i := 0; i < b.N; i++ {
   262  		m := IntMap{}
   263  		kv := make([]uint64, N*2)
   264  		for i := 0; i < N; i++ {
   265  			x := uint64(rand.Int())
   266  			kv[i] = x
   267  			kv[i+N] = x
   268  		}
   269  		m.BatchSet(kv)
   270  	}
   271  }
   272  
   273  func BenchmarkAdd(b *testing.B) {
   274  	x, y, z := byte(rand.Int()), byte(rand.Int()), byte(rand.Int())
   275  	for i := 0; i < b.N; i++ {
   276  		for k := 0; k < 100; k++ {
   277  			if a := y + x; a == z {
   278  				b.Fatal(x, y)
   279  			}
   280  		}
   281  	}
   282  }
   283  
   284  func BenchmarkXorAdd(b *testing.B) {
   285  	x, y, z := byte(rand.Int()), byte(rand.Int()), byte(rand.Int())
   286  	for i := 0; i < b.N; i++ {
   287  		for k := 0; k < 100; k++ {
   288  			if a := x<<4 | y; a == z {
   289  				b.Fatal(x, y)
   290  			}
   291  		}
   292  	}
   293  }