-
-
Save JelteF/1251f180966eb974d7732ea6c3d3b7ff to your computer and use it in GitHub Desktop.
Benchmark comparing map access vs slice search
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 94, you need to add a break