v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/hashtable/table_test.go (about)

     1  package hashtable_test
     2  
     3  import (
     4  	"runtime"
     5  	"strconv"
     6  	"sync"
     7  	"testing"
     8  
     9  	"v8.run/go/exp/fastrand"
    10  	"v8.run/go/exp/hash"
    11  	"v8.run/go/exp/hashtable"
    12  	"v8.run/go/exp/util/slice"
    13  )
    14  
    15  const size = 1 << 20
    16  
    17  var keys []string = func() []string {
    18  	k := make([]string, size)
    19  	for i := range k {
    20  		k[i] = strconv.Itoa(i * 10000)
    21  	}
    22  	return k
    23  }()
    24  
    25  func TestTableInsert(t *testing.T) {
    26  	table := hashtable.New[string, string](1, hash.MemHashString64)
    27  	cpus := runtime.NumCPU()
    28  	fastrand.ShuffleSlice(keys)
    29  	ks := slice.Chunk(keys, size/cpus)
    30  
    31  	var wg sync.WaitGroup
    32  	for i := range ks {
    33  		wg.Add(1)
    34  		go func(i int) {
    35  			defer wg.Done()
    36  
    37  			for j := range ks[i] {
    38  				table.Insert(ks[i][j], ks[i][j])
    39  				runtime.Gosched()
    40  				table.Insert(ks[i][j], ks[i][j])
    41  			}
    42  		}(i)
    43  	}
    44  	wg.Wait()
    45  
    46  	fastrand.ShuffleSlice(keys)
    47  	for i := range keys {
    48  		v, ok := table.Lookup(keys[i])
    49  		if !ok || v != keys[i] {
    50  			t.Fatalf("Expected %q, got %q", keys[i], v)
    51  		}
    52  	}
    53  }
    54  
    55  func TestTableDelete(t *testing.T) {
    56  	table := hashtable.New[string, string](1, hash.MemHashString64)
    57  	cpus := runtime.NumCPU()
    58  	fastrand.ShuffleSlice(keys)
    59  	ks := slice.Chunk(keys, size/cpus)
    60  
    61  	var wg sync.WaitGroup
    62  	for i := range ks {
    63  		wg.Add(1)
    64  		go func(i int) {
    65  			defer wg.Done()
    66  
    67  			for j := range ks[i] {
    68  				table.Insert(ks[i][j], ks[i][j])
    69  				runtime.Gosched()
    70  				table.Delete(ks[i][j])
    71  			}
    72  		}(i)
    73  	}
    74  	wg.Wait()
    75  
    76  	fastrand.ShuffleSlice(keys)
    77  	for i := range keys {
    78  		v, ok := table.Lookup(keys[i])
    79  		if ok {
    80  			t.Fatalf("Table:%s Expected null, got %q", keys[i], v)
    81  		}
    82  	}
    83  }
    84  
    85  const size2 = 1 << 18
    86  
    87  var keys2 []string = func() []string {
    88  	k := make([]string, size2)
    89  	for i := range k {
    90  		k[i] = strconv.Itoa(i * 10000)
    91  	}
    92  	return k
    93  }()
    94  
    95  func BenchmarkTableRead100(b *testing.B) {
    96  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
    97  
    98  	for i := range keys2 {
    99  		table.Insert(keys2[i], 0)
   100  	}
   101  	b.SetBytes(int64(size2 * 10))
   102  	b.ResetTimer()
   103  	b.RunParallel(func(p *testing.PB) {
   104  		for p.Next() {
   105  			for i := range keys2 {
   106  				table.Lookup(keys2[i])
   107  				table.Lookup(keys2[i])
   108  				table.Lookup(keys2[i])
   109  				table.Lookup(keys2[i])
   110  				table.Lookup(keys2[i])
   111  				table.Lookup(keys2[i])
   112  				table.Lookup(keys2[i])
   113  				table.Lookup(keys2[i])
   114  				table.Lookup(keys2[i])
   115  				table.Lookup(keys2[i])
   116  			}
   117  		}
   118  	})
   119  }
   120  
   121  func BenchmarkSyncMapRead100(b *testing.B) {
   122  	table := sync.Map{}
   123  
   124  	for i := range keys2 {
   125  		table.Store(keys2[i], 0)
   126  	}
   127  	b.SetBytes(int64(size2 * 10))
   128  	b.ResetTimer()
   129  	b.RunParallel(func(p *testing.PB) {
   130  		for p.Next() {
   131  			for i := range keys2 {
   132  				table.Load(keys2[i])
   133  				table.Load(keys2[i])
   134  				table.Load(keys2[i])
   135  				table.Load(keys2[i])
   136  				table.Load(keys2[i])
   137  				table.Load(keys2[i])
   138  				table.Load(keys2[i])
   139  				table.Load(keys2[i])
   140  				table.Load(keys2[i])
   141  				table.Load(keys2[i])
   142  			}
   143  		}
   144  	})
   145  }
   146  
   147  func BenchmarkTableRead90Write10(b *testing.B) {
   148  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
   149  
   150  	for i := range keys2 {
   151  		table.Insert(keys2[i], 0)
   152  	}
   153  	b.SetBytes(int64(size2 * 10))
   154  	b.ResetTimer()
   155  	b.RunParallel(func(p *testing.PB) {
   156  		for p.Next() {
   157  			for i := range keys2 {
   158  				table.Lookup(keys2[i])
   159  				table.Lookup(keys2[i])
   160  				table.Lookup(keys2[i])
   161  				table.Lookup(keys2[i])
   162  				table.Lookup(keys2[i])
   163  				table.Lookup(keys2[i])
   164  				table.Lookup(keys2[i])
   165  				table.Lookup(keys2[i])
   166  				table.Lookup(keys2[i])
   167  				table.Insert(keys2[i], 0)
   168  			}
   169  		}
   170  	})
   171  }
   172  
   173  func BenchmarkSyncMapRead90Write10(b *testing.B) {
   174  	table := sync.Map{}
   175  
   176  	for i := range keys2 {
   177  		table.Store(keys2[i], 0)
   178  	}
   179  	b.SetBytes(int64(size2 * 10))
   180  	b.ResetTimer()
   181  	b.RunParallel(func(p *testing.PB) {
   182  		for p.Next() {
   183  			for i := range keys2 {
   184  				table.Load(keys2[i])
   185  				table.Load(keys2[i])
   186  				table.Load(keys2[i])
   187  				table.Load(keys2[i])
   188  				table.Load(keys2[i])
   189  				table.Load(keys2[i])
   190  				table.Load(keys2[i])
   191  				table.Load(keys2[i])
   192  				table.Load(keys2[i])
   193  				table.Store(keys2[i], 0)
   194  			}
   195  		}
   196  	})
   197  }
   198  
   199  func BenchmarkTableRead70Write30(b *testing.B) {
   200  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
   201  
   202  	for i := range keys2 {
   203  		table.Insert(keys2[i], 0)
   204  	}
   205  	b.SetBytes(int64(size2 * 10))
   206  	b.ResetTimer()
   207  	b.RunParallel(func(p *testing.PB) {
   208  		for p.Next() {
   209  			for i := range keys2 {
   210  				table.Lookup(keys2[i])
   211  				table.Lookup(keys2[i])
   212  				table.Lookup(keys2[i])
   213  				table.Lookup(keys2[i])
   214  				table.Lookup(keys2[i])
   215  				table.Lookup(keys2[i])
   216  				table.Lookup(keys2[i])
   217  				table.Insert(keys2[i], 0)
   218  				table.Insert(keys2[i], 0)
   219  				table.Insert(keys2[i], 0)
   220  			}
   221  		}
   222  	})
   223  }
   224  
   225  func BenchmarkSyncMapRead70Write30(b *testing.B) {
   226  	table := sync.Map{}
   227  
   228  	for i := range keys2 {
   229  		table.Store(keys2[i], 0)
   230  	}
   231  	b.SetBytes(int64(size2 * 10))
   232  	b.ResetTimer()
   233  	b.RunParallel(func(p *testing.PB) {
   234  		for p.Next() {
   235  			for i := range keys2 {
   236  				table.Load(keys2[i])
   237  				table.Load(keys2[i])
   238  				table.Load(keys2[i])
   239  				table.Load(keys2[i])
   240  				table.Load(keys2[i])
   241  				table.Load(keys2[i])
   242  				table.Load(keys2[i])
   243  				table.Store(keys2[i], 0)
   244  				table.Store(keys2[i], 0)
   245  				table.Store(keys2[i], 0)
   246  			}
   247  		}
   248  	})
   249  }
   250  
   251  func BenchmarkTableRead50Write50(b *testing.B) {
   252  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
   253  
   254  	for i := range keys2 {
   255  		table.Insert(keys2[i], 0)
   256  	}
   257  	b.SetBytes(int64(size2 * 10))
   258  	b.ResetTimer()
   259  	b.RunParallel(func(p *testing.PB) {
   260  		for p.Next() {
   261  			for i := range keys2 {
   262  				table.Lookup(keys2[i])
   263  				table.Lookup(keys2[i])
   264  				table.Lookup(keys2[i])
   265  				table.Lookup(keys2[i])
   266  				table.Lookup(keys2[i])
   267  				table.Insert(keys2[i], 0)
   268  				table.Insert(keys2[i], 0)
   269  				table.Insert(keys2[i], 0)
   270  				table.Insert(keys2[i], 0)
   271  				table.Insert(keys2[i], 0)
   272  			}
   273  		}
   274  	})
   275  }
   276  
   277  func BenchmarkSyncMapRead50Write50(b *testing.B) {
   278  	table := sync.Map{}
   279  
   280  	for i := range keys2 {
   281  		table.Store(keys2[i], 0)
   282  	}
   283  	b.SetBytes(int64(size2 * 10))
   284  	b.ResetTimer()
   285  	b.RunParallel(func(p *testing.PB) {
   286  		for p.Next() {
   287  			for i := range keys2 {
   288  				table.Load(keys2[i])
   289  				table.Load(keys2[i])
   290  				table.Load(keys2[i])
   291  				table.Load(keys2[i])
   292  				table.Load(keys2[i])
   293  				table.Store(keys2[i], 0)
   294  				table.Store(keys2[i], 0)
   295  				table.Store(keys2[i], 0)
   296  				table.Store(keys2[i], 0)
   297  				table.Store(keys2[i], 0)
   298  			}
   299  		}
   300  	})
   301  }
   302  
   303  func BenchmarkTableRead30Write70(b *testing.B) {
   304  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
   305  
   306  	for i := range keys2 {
   307  		table.Insert(keys2[i], 0)
   308  	}
   309  	b.SetBytes(int64(size2 * 10))
   310  	b.ResetTimer()
   311  	b.RunParallel(func(p *testing.PB) {
   312  		for p.Next() {
   313  			for i := range keys2 {
   314  				table.Lookup(keys2[i])
   315  				table.Lookup(keys2[i])
   316  				table.Lookup(keys2[i])
   317  				table.Insert(keys2[i], 0)
   318  				table.Insert(keys2[i], 0)
   319  				table.Insert(keys2[i], 0)
   320  				table.Insert(keys2[i], 0)
   321  				table.Insert(keys2[i], 0)
   322  				table.Insert(keys2[i], 0)
   323  				table.Insert(keys2[i], 0)
   324  			}
   325  		}
   326  	})
   327  }
   328  
   329  func BenchmarkSyncMapRead30Write70(b *testing.B) {
   330  	table := sync.Map{}
   331  
   332  	for i := range keys2 {
   333  		table.Store(keys2[i], 0)
   334  	}
   335  	b.SetBytes(int64(size2 * 10))
   336  	b.ResetTimer()
   337  	b.RunParallel(func(p *testing.PB) {
   338  		for p.Next() {
   339  			for i := range keys2 {
   340  				table.Load(keys2[i])
   341  				table.Load(keys2[i])
   342  				table.Load(keys2[i])
   343  				table.Store(keys2[i], 0)
   344  				table.Store(keys2[i], 0)
   345  				table.Store(keys2[i], 0)
   346  				table.Store(keys2[i], 0)
   347  				table.Store(keys2[i], 0)
   348  				table.Store(keys2[i], 0)
   349  				table.Store(keys2[i], 0)
   350  			}
   351  		}
   352  	})
   353  }
   354  
   355  func BenchmarkTableRead10Write90(b *testing.B) {
   356  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
   357  
   358  	for i := range keys2 {
   359  		table.Insert(keys2[i], 0)
   360  	}
   361  	b.SetBytes(int64(size2 * 10))
   362  	b.ResetTimer()
   363  	b.RunParallel(func(p *testing.PB) {
   364  		for p.Next() {
   365  			for i := range keys2 {
   366  				table.Lookup(keys2[i])
   367  				table.Insert(keys2[i], 0)
   368  				table.Insert(keys2[i], 0)
   369  				table.Insert(keys2[i], 0)
   370  				table.Insert(keys2[i], 0)
   371  				table.Insert(keys2[i], 0)
   372  				table.Insert(keys2[i], 0)
   373  				table.Insert(keys2[i], 0)
   374  				table.Insert(keys2[i], 0)
   375  				table.Insert(keys2[i], 0)
   376  			}
   377  		}
   378  	})
   379  }
   380  
   381  func BenchmarkSyncMapRead10Write90(b *testing.B) {
   382  	table := sync.Map{}
   383  
   384  	for i := range keys2 {
   385  		table.Store(keys2[i], 0)
   386  	}
   387  	b.SetBytes(int64(size2 * 10))
   388  	b.ResetTimer()
   389  	b.RunParallel(func(p *testing.PB) {
   390  		for p.Next() {
   391  			for i := range keys2 {
   392  				table.Load(keys2[i])
   393  				table.Store(keys2[i], 0)
   394  				table.Store(keys2[i], 0)
   395  				table.Store(keys2[i], 0)
   396  				table.Store(keys2[i], 0)
   397  				table.Store(keys2[i], 0)
   398  				table.Store(keys2[i], 0)
   399  				table.Store(keys2[i], 0)
   400  				table.Store(keys2[i], 0)
   401  				table.Store(keys2[i], 0)
   402  			}
   403  		}
   404  	})
   405  }
   406  
   407  func BenchmarkTableWrite100(b *testing.B) {
   408  	table := hashtable.New[string, uint64](size2, hash.MemHashString64)
   409  
   410  	for i := range keys2 {
   411  		table.Insert(keys2[i], 0)
   412  	}
   413  	b.SetBytes(int64(size2 * 10))
   414  	b.ResetTimer()
   415  	b.RunParallel(func(p *testing.PB) {
   416  		for p.Next() {
   417  			for i := range keys2 {
   418  				table.Insert(keys2[i], 0)
   419  				table.Insert(keys2[i], 0)
   420  				table.Insert(keys2[i], 0)
   421  				table.Insert(keys2[i], 0)
   422  				table.Insert(keys2[i], 0)
   423  				table.Insert(keys2[i], 0)
   424  				table.Insert(keys2[i], 0)
   425  				table.Insert(keys2[i], 0)
   426  				table.Insert(keys2[i], 0)
   427  				table.Insert(keys2[i], 0)
   428  			}
   429  		}
   430  	})
   431  }
   432  
   433  func BenchmarkSyncMapWrite100(b *testing.B) {
   434  	table := sync.Map{}
   435  
   436  	for i := range keys2 {
   437  		table.Store(keys2[i], 0)
   438  	}
   439  	b.SetBytes(int64(size2 * 10))
   440  	b.ResetTimer()
   441  	b.RunParallel(func(p *testing.PB) {
   442  		for p.Next() {
   443  			for i := range keys2 {
   444  				table.Store(keys2[i], 0)
   445  				table.Store(keys2[i], 0)
   446  				table.Store(keys2[i], 0)
   447  				table.Store(keys2[i], 0)
   448  				table.Store(keys2[i], 0)
   449  				table.Store(keys2[i], 0)
   450  				table.Store(keys2[i], 0)
   451  				table.Store(keys2[i], 0)
   452  				table.Store(keys2[i], 0)
   453  				table.Store(keys2[i], 0)
   454  			}
   455  		}
   456  	})
   457  }