dolthub/swiss

The performance of swiss Get() is worse than go map at capacity 1~500.

ankisme opened this issue · 0 comments

Here is the benchmark.

I found the performance of Get() method is worse than go map get when the capacity is 1~500.

And in my project, call times of Get() method is much more than Put(). And the capacity of map is often less than 500.

So the performance of swiss is not good enough. Wish to improve it.

goos: windows
goarch: amd64
pkg: web/util/listutil
cpu: Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
BenchmarkCreateSwissMap
BenchmarkCreateSwissMap-8         499999              3184 ns/op           10128
 B/op          3 allocs/op
BenchmarkCreateGoMap
BenchmarkCreateGoMap-8            249999              5692 ns/op           20504
 B/op          2 allocs/op
BenchmarkSwissMapPut
BenchmarkSwissMapPut-8             35820             37102 ns/op           34624
 B/op         15 allocs/op
BenchmarkGoMapPut
BenchmarkGoMapPut-8                28435             44501 ns/op           43173
 B/op         42 allocs/op
BenchmarkSwissMapGet
BenchmarkSwissMapGet-8            226414              5092 ns/op               0
 B/op          0 allocs/op
BenchmarkGoMapGet
BenchmarkGoMapGet-8               292682              4278 ns/op               0
 B/op          0 allocs/op
BenchmarkSwissMapIterate
BenchmarkSwissMapIterate-8        750000              1616 ns/op               0
 B/op          0 allocs/op
BenchmarkGoMapIterate
BenchmarkGoMapIterate-8           249999              4900 ns/op               0
 B/op          0 allocs/op
PASS
package listutil_test

import (
	"github.com/dolthub/swiss"
	"testing"
)

const capacity = 500

func CreateSwissMap() *swiss.Map[int, int] {
	m := swiss.NewMap[int, int](0)

	for i := 1; i <= capacity; i++ {
		m.Put(i, i)
	}

	return m
}

func CreateMap() map[int]int {
	m := map[int]int{}

	for i := 1; i <= capacity; i++ {
		m[i] = i
	}

	return m
}

func BenchmarkCreateSwissMap(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		m := swiss.NewMap[int, int](capacity)
		if m != nil {

		}
	}
}

func BenchmarkCreateGoMap(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		m := make(map[int]int, capacity)
		if m != nil {

		}
	}
}

func BenchmarkSwissMapPut(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		CreateSwissMap()
	}
}

func BenchmarkGoMapPut(b *testing.B) {
	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		CreateMap()
	}
}

func BenchmarkSwissMapGet(b *testing.B) {
	m := CreateSwissMap()
	size := m.Count()

	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		for i := 1; i <= size; i++ {
			v, ok := m.Get(i)
			if !ok || v == 0 {
				panic(`not found`)
			}
		}
	}
}

func BenchmarkGoMapGet(b *testing.B) {
	m := CreateMap()
	size := len(m)

	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		for i := 1; i <= size; i++ {
			v, ok := m[i]
			if !ok || v == 0 {
				panic(`not found`)
			}
		}
	}
}

func BenchmarkSwissMapIterate(b *testing.B) {
	m := CreateSwissMap()

	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		m.Iter(func(k int, v int) (stop bool) {
			if k <= 0 {
				panic(1)
			}

			if v == 0 {
				panic(1)
			}

			return false
		})
	}
}

func BenchmarkGoMapIterate(b *testing.B) {
	m := CreateMap()

	b.ReportAllocs()
	b.ResetTimer()

	for n := 0; n < b.N; n++ {
		for k, v := range m {
			if k <= 0 {
				panic(1)
			}

			if v == 0 {
				panic(1)
			}
		}
	}
}