Skip to content

faststringmap is only faster when keys are shorter 7 symbols #5

@zhulik

Description

@zhulik

I was evaluating faststringmap for my use case and wrote a benchmark that compares lookup times of standard map and faststringmap. In the beginning the key length was 36 symbols(length of a UUID with dashes), the result of faststringmap was about 10 times worse than the result of standard map. So I limited the length of the keys in my benchmark to 6 and only then faststringmap became faster:

package trie_test

import (
	"testing"

	"github.com/google/uuid"
	"github.com/sensiblecodeio/faststringmap"
)

const (
	keysCount = 1000
)

type exampleSource map[string]uint32

func (s exampleSource) AppendKeys(a []string) []string {
	for k := range s {
		a = append(a, k)
	}
	return a
}

func (s exampleSource) Get(k string) uint32 {
	return s[k]
}

var (
	keys    []string
	hashMap exampleSource
	fastMap faststringmap.Uint32Store
)

func init() {
	keys = make([]string, keysCount)

	hashMap = exampleSource{}

	for i := 0; i < keysCount; i++ {
		keys[i] = uuid.NewString()[0:6]
		hashMap[keys[i]] = 1
	}

	fastMap = faststringmap.NewUint32Store(hashMap)
}

func BenchmarkMap(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for _, key := range keys {
			if v, ok := hashMap[key]; v != 1 || !ok {
				b.Fail()
			}
		}
	}
}

func BenchmarkFastStringMap(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for _, key := range keys {
			if v, ok := fastMap.LookupString(key); v != 1 || !ok {
				b.Fail()
			}
		}
	}
}

Results for key length of 36:

goos: linux
goarch: amd64
pkg: github.com/zhulik/go-eventbus/trie
cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics     
BenchmarkMap-16                   134596              8464 ns/op
BenchmarkFastStringMap-16          14326             84213 ns/op
PASS
ok      github.com/zhulik/go-eventbus/trie      3.311s

Results for key length of 6:

goos: linux
goarch: amd64
pkg: github.com/zhulik/go-eventbus/trie
cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics     
BenchmarkMap-16                   132898              8484 ns/op
BenchmarkFastStringMap-16         140976              8254 ns/op
PASS
ok      github.com/zhulik/go-eventbus/trie      2.495s

Am I cooking the data structure wrong, or it is by design?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions