github.com/iainanderson83/datastructures@v0.0.4-0.20191103204413-889e20b53bcf/hashmap/hashmap_test.go (about)

     1  package hashmap
     2  
     3  import (
     4  	"math/rand"
     5  	"sync"
     6  	"testing"
     7  )
     8  
     9  var (
    10  	redistributionTuples = []entry{}
    11  )
    12  
    13  func TestMain(m *testing.M) {
    14  	rand.Seed(42)
    15  
    16  	ma := make(map[string]struct{})
    17  
    18  	var i int
    19  	for {
    20  		key := wordList[rand.Intn(len(wordList))]
    21  		if _, ok := ma[key]; ok {
    22  			continue
    23  		}
    24  		ma[key] = struct{}{}
    25  		tpl := entry{key: key, value: wordList[rand.Intn(len(wordList))]}
    26  		redistributionTuples = append(redistributionTuples, tpl)
    27  
    28  		i++
    29  		if i > 50 {
    30  			break
    31  		}
    32  	}
    33  
    34  	m.Run()
    35  }
    36  
    37  func TestMap(t *testing.T) {
    38  	tests := map[string]struct {
    39  		debug   bool
    40  		adds    []entry
    41  		lookups []entry
    42  	}{
    43  		"SingleValue": {
    44  			false,
    45  			[]entry{{key: "hello", value: "world"}},
    46  			[]entry{{key: "hello", value: "world"}},
    47  		},
    48  		"OverwriteValue": {
    49  			false,
    50  			[]entry{{key: "hello", value: "world"}, {key: "hello", value: "foo"}},
    51  			[]entry{{key: "hello", value: "foo"}},
    52  		},
    53  		"MultipleValues": {
    54  			false,
    55  			[]entry{{key: "hello", value: "world"}, {key: "foo", value: "bar"}, {key: "baz", value: "bubbles"}, {key: "hello", value: "foo"}},
    56  			[]entry{{key: "foo", value: "bar"}, {key: "baz", value: "bubbles"}, {key: "hello", value: "foo"}},
    57  		},
    58  		"Redistribute": {
    59  			false,
    60  			redistributionTuples,
    61  			redistributionTuples,
    62  		},
    63  	}
    64  
    65  	for name, test := range tests {
    66  		t.Run(name, func(t *testing.T) {
    67  			m := NewFNV1aHashmap()
    68  			m2 := NewRuntimeHashmap()
    69  			for _, tpl := range test.adds {
    70  				m.Add(tpl.key, tpl.value)
    71  				m2.Add(tpl.key, tpl.value)
    72  			}
    73  
    74  			for _, tpl := range test.lookups {
    75  				v, _ := m.Lookup(tpl.key)
    76  				if v != tpl.value {
    77  					t.Fatalf("%s: expected '%v', got '%v'", tpl.key, tpl.value, v)
    78  				}
    79  
    80  				v2, _ := m2.Lookup(tpl.key)
    81  				if v2 != tpl.value {
    82  					t.Fatalf("%s: expected '%v', got '%v'", tpl.key, tpl.value, v2)
    83  				}
    84  			}
    85  		})
    86  	}
    87  }
    88  
    89  func BenchmarkRuntimeHashmap(b *testing.B) {
    90  	b.ReportAllocs()
    91  
    92  	for i := 0; i < b.N; i++ {
    93  		m := NewRuntimeHashmap()
    94  		for _, tpl := range redistributionTuples {
    95  			m.Add(tpl.key, tpl.value)
    96  		}
    97  
    98  		for _, tpl := range redistributionTuples {
    99  			v, _ := m.Lookup(tpl.key)
   100  			_ = v
   101  		}
   102  	}
   103  }
   104  
   105  func BenchmarkFNV1aHashmap(b *testing.B) {
   106  	b.ReportAllocs()
   107  
   108  	for i := 0; i < b.N; i++ {
   109  		m := NewFNV1aHashmap()
   110  		for _, tpl := range redistributionTuples {
   111  			m.Add(tpl.key, tpl.value)
   112  		}
   113  
   114  		for _, tpl := range redistributionTuples {
   115  			v, _ := m.Lookup(tpl.key)
   116  			_ = v
   117  		}
   118  	}
   119  }
   120  
   121  func BenchmarkGoHashmap(b *testing.B) {
   122  	b.ReportAllocs()
   123  
   124  	for i := 0; i < b.N; i++ {
   125  		m := make(map[string]interface{})
   126  		for _, tpl := range redistributionTuples {
   127  			m[tpl.key] = tpl.value
   128  		}
   129  
   130  		for _, tpl := range redistributionTuples {
   131  			v := m[tpl.key]
   132  			_ = v
   133  		}
   134  	}
   135  }
   136  
   137  func BenchmarkXXHashmap(b *testing.B) {
   138  	b.ReportAllocs()
   139  
   140  	for i := 0; i < b.N; i++ {
   141  		m := NewXXHashmap()
   142  		for _, tpl := range redistributionTuples {
   143  			m.Add(tpl.key, tpl.value)
   144  		}
   145  
   146  		for _, tpl := range redistributionTuples {
   147  			v, _ := m.Lookup(tpl.key)
   148  			_ = v
   149  		}
   150  	}
   151  }
   152  
   153  func BenchmarkGoSyncMap(b *testing.B) {
   154  	b.ReportAllocs()
   155  
   156  	for i := 0; i < b.N; i++ {
   157  		m := &sync.Map{}
   158  		for _, tpl := range redistributionTuples {
   159  			m.Store(tpl.key, tpl.value)
   160  		}
   161  
   162  		for _, tpl := range redistributionTuples {
   163  			v, _ := m.Load(tpl.key)
   164  			_ = v
   165  		}
   166  	}
   167  }