Skip to content

Instantly share code, notes, and snippets.

@JelteF
Forked from grahamking/slicemap_test.go
Last active May 12, 2023 17:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JelteF/1251f180966eb974d7732ea6c3d3b7ff to your computer and use it in GitHub Desktop.
Save JelteF/1251f180966eb974d7732ea6c3d3b7ff to your computer and use it in GitHub Desktop.
Benchmark comparing map access vs slice search
package main
import (
"math/rand"
"testing"
"time"
)
const (
numItems = 100 // change this to see how number of items affects speed
keyLen = 10
valLen = 20
)
func gen(length int) string {
var s string
for i := 0; i < length; i++ {
s += string(rand.Int31n(126-48) + int32(48))
}
return s
}
type Item struct {
Key string
Val string
}
func randomKVKey(theArr []*Item) string {
return theArr[rand.Int31n(int32(len(theArr)))].Key
}
func randomIntKey(theArr []int) int {
return theArr[rand.Int31n(int32(len(theArr)))]
}
/********************
* A typical key/value storage, once as map[string]string, once
* as []*Item{string,string}.
*/
func populateKV(theArr []*Item, theMap map[string]string) {
var k, v string
rand.Seed(time.Now().UnixNano())
for i := 0; i < numItems; i++ {
k = gen(keyLen)
v = gen(valLen)
theMap[k] = v
theArr[i] = &Item{Key: k, Val: v}
}
}
var intResult = 0
var stringResult = ""
func BenchmarkBaselineKV(b *testing.B) {
theMap := make(map[string]string, numItems)
theArr := make([]*Item, numItems)
populateKV(theArr, theMap)
b.ResetTimer()
for i := 0; i < b.N; i++ {
stringResult = randomKVKey(theArr)
}
}
func BenchmarkKVItemSlice(b *testing.B) {
theMap := make(map[string]string, numItems)
theArr := make([]*Item, numItems)
populateKV(theArr, theMap)
b.ResetTimer()
for i := 0; i < b.N; i++ {
q := randomKVKey(theArr)
for _, item := range theArr {
if item.Key == q {
stringResult = item.Key
break
}
}
}
}
func BenchmarkKVStringMap(b *testing.B) {
theMap := make(map[string]string, numItems)
theArr := make([]*Item, numItems)
populateKV(theArr, theMap)
b.ResetTimer()
for i := 0; i < b.N; i++ {
q := randomKVKey(theArr)
if theMap[q] != "" {
stringResult = q
}
}
}
/********************
* A set of integers, once as []int, once as map[int]struct{}
*/
func populateInts(theArr []int, theMap map[int]struct{}) {
rand.Seed(time.Now().UnixNano())
for i := 0; i < numItems; i++ {
num := rand.Int()
theArr[i] = num
theMap[num] = struct{}{}
}
}
func BenchmarkBaselineSetInt(b *testing.B) {
theMap := make(map[int]struct{}, numItems)
theArr := make([]int, numItems)
populateInts(theArr, theMap)
b.ResetTimer()
for i := 0; i < b.N; i++ {
intResult = randomIntKey(theArr)
}
}
func BenchmarkSetIntSlice(b *testing.B) {
theMap := make(map[int]struct{}, numItems)
theArr := make([]int, numItems)
populateInts(theArr, theMap)
b.ResetTimer()
for i := 0; i < b.N; i++ {
q := randomIntKey(theArr)
for _, value := range theArr {
if value == q {
intResult = q
break
}
}
}
}
func BenchmarkSetIntMap(b *testing.B) {
theMap := make(map[int]struct{}, numItems)
theArr := make([]int, numItems)
populateInts(theArr, theMap)
b.ResetTimer()
for i := 0; i < b.N; i++ {
q := randomIntKey(theArr)
if _, ok := theMap[q]; ok {
intResult = q
}
}
}
@emilianobilli
Copy link

Line 94, you need to add a break

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment