192 lines
4.7 KiB
Go
192 lines
4.7 KiB
Go
package pmap
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func hash(k Key) uint32 {
|
|
//u := uint(k.(int))*6364136223846793005 + 1
|
|
//return uint32(u >> 32)
|
|
u := uint(k) //u := uint(k.(int))
|
|
return uint32(u + u>>32)
|
|
}
|
|
|
|
// FIXME: collisions can cause allocations during Get
|
|
|
|
func TestPmap(t *testing.T) {
|
|
p := New(hash)
|
|
const numElems = 100
|
|
for i := range iter(numElems) {
|
|
p = p.Set(i, i)
|
|
}
|
|
if p.Len() != numElems {
|
|
t.Fatalf("Len() = %v, want %v", p.Len(), numElems)
|
|
}
|
|
for i := range iter(numElems) {
|
|
v, ok := p.Get(i)
|
|
if v != i || !ok {
|
|
t.Errorf("Get(%d) = %v %v, want %v %v", i, v, ok, i, true)
|
|
}
|
|
}
|
|
fmt.Print(p.(pmap).stats())
|
|
}
|
|
|
|
func BenchmarkGet(b *testing.B) {
|
|
b.Run("size=10", func(b *testing.B) { benchmarkGet(b, 10) })
|
|
b.Run("size=100", func(b *testing.B) { benchmarkGet(b, 100) })
|
|
b.Run("size=1000", func(b *testing.B) { benchmarkGet(b, 1000) })
|
|
b.Run("size=10000", func(b *testing.B) { benchmarkGet(b, 10000) })
|
|
//b.Run("size=100000", func(b *testing.B) { benchmarkGet(b, 100000) })
|
|
//b.Run("size=1000000", func(b *testing.B) { benchmarkGet(b, 1000000) })
|
|
}
|
|
|
|
func BenchmarkGetAbsent(b *testing.B) {
|
|
b.Run("size=10", func(b *testing.B) { benchmarkGetAbsent(b, 10) })
|
|
b.Run("size=100", func(b *testing.B) { benchmarkGetAbsent(b, 100) })
|
|
b.Run("size=1000", func(b *testing.B) { benchmarkGetAbsent(b, 1000) })
|
|
b.Run("size=10000", func(b *testing.B) { benchmarkGetAbsent(b, 10000) })
|
|
}
|
|
|
|
func benchmarkGet(b *testing.B, numElems int) {
|
|
p := New(hash)
|
|
for i := range iter(numElems) {
|
|
p = p.Set(i, i)
|
|
}
|
|
if p.Len() != numElems {
|
|
b.Fatalf("Len() = %v, want %v", p.Len(), numElems)
|
|
}
|
|
b.ResetTimer()
|
|
i := 0
|
|
for range iter(b.N) {
|
|
v, ok := p.Get(i)
|
|
if v != i || !ok {
|
|
b.Errorf("Get(%d) = %v %v, want %v %v", i, v, ok, i, true)
|
|
}
|
|
i++
|
|
if i >= numElems {
|
|
i = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
func benchmarkGetAbsent(b *testing.B, numElems int) {
|
|
p := New(hash)
|
|
for i := range iter(numElems) {
|
|
p = p.Set(i-numElems, i)
|
|
}
|
|
if p.Len() != numElems {
|
|
b.Fatalf("Len() = %v, want %v", p.Len(), numElems)
|
|
}
|
|
b.ResetTimer()
|
|
i := 0
|
|
for range iter(b.N) {
|
|
v, ok := p.Get(i)
|
|
if ok {
|
|
b.Errorf("Get(%d) = %v %v, want %v %v", i, v, ok, 0, false)
|
|
}
|
|
i++
|
|
}
|
|
}
|
|
|
|
func iter(n int) []struct{} {
|
|
return make([]struct{}, n)
|
|
}
|
|
|
|
func BenchmarkHmapGet_baseline(b *testing.B) {
|
|
b.Run("size=10", func(b *testing.B) { benchmarkHmapGet(b, 10) })
|
|
b.Run("size=100", func(b *testing.B) { benchmarkHmapGet(b, 100) })
|
|
b.Run("size=1000", func(b *testing.B) { benchmarkHmapGet(b, 1000) })
|
|
b.Run("size=10000", func(b *testing.B) { benchmarkHmapGet(b, 10000) })
|
|
b.Run("size=100000", func(b *testing.B) { benchmarkHmapGet(b, 100000) })
|
|
b.Run("size=1000000", func(b *testing.B) { benchmarkHmapGet(b, 1000000) })
|
|
}
|
|
|
|
func benchmarkHmapGet(b *testing.B, numElems int) {
|
|
h := make(map[int]Value)
|
|
for i := range iter(numElems) {
|
|
h[i] = i
|
|
}
|
|
if len(h) != numElems {
|
|
b.Fatalf("Len() = %v, want %v", len(h), numElems)
|
|
}
|
|
b.ResetTimer()
|
|
i := 0
|
|
for range iter(b.N) {
|
|
v, ok := h[i]
|
|
if v != i || !ok {
|
|
b.Errorf("h[%d] = %v %v, want %v %v", i, v, ok, i, true)
|
|
}
|
|
i++
|
|
if i >= numElems {
|
|
i = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkSet(b *testing.B) {
|
|
b.Run("size=10", func(b *testing.B) { benchmarkSet(b, 10) })
|
|
b.Run("size=100", func(b *testing.B) { benchmarkSet(b, 100) })
|
|
b.Run("size=1000", func(b *testing.B) { benchmarkSet(b, 1000) })
|
|
b.Run("size=10000", func(b *testing.B) { benchmarkSet(b, 10000) })
|
|
if !testing.Short() {
|
|
b.Run("size=100000", func(b *testing.B) { benchmarkSet(b, 100000) })
|
|
}
|
|
}
|
|
|
|
func benchmarkSet(b *testing.B, numElems int) {
|
|
p := New(hash)
|
|
for i := range iter(numElems) {
|
|
p = p.Set(i, i)
|
|
}
|
|
if p.Len() != numElems {
|
|
b.Fatalf("Len() = %v, want %v", p.Len(), numElems)
|
|
}
|
|
b.ResetTimer()
|
|
for i := range iter(b.N) {
|
|
k := i + numElems
|
|
_ = p.Set(k, k)
|
|
}
|
|
}
|
|
|
|
func BenchmarkHmapSet_baseline(b *testing.B) {
|
|
b.Run("size=10", func(b *testing.B) { benchmarkHmapSet(b, 10) })
|
|
b.Run("size=100", func(b *testing.B) { benchmarkHmapSet(b, 100) })
|
|
b.Run("size=1000", func(b *testing.B) { benchmarkHmapSet(b, 1000) })
|
|
b.Run("size=10000", func(b *testing.B) { benchmarkHmapSet(b, 10000) })
|
|
if !testing.Short() {
|
|
b.Run("size=100000", func(b *testing.B) { benchmarkHmapSet(b, 100000) })
|
|
}
|
|
}
|
|
|
|
func benchmarkHmapSet(b *testing.B, numElems int) {
|
|
h := make(map[int]Value)
|
|
for i := range iter(numElems) {
|
|
h[i] = i
|
|
}
|
|
if len(h) != numElems {
|
|
b.Fatalf("Len() = %v, want %v", len(h), numElems)
|
|
}
|
|
b.ResetTimer()
|
|
for i := range iter(b.N) {
|
|
k := i + numElems
|
|
h[k] = k
|
|
delete(h, k)
|
|
}
|
|
}
|
|
|
|
func TestBitmap(t *testing.T) {
|
|
n := node{bitmap: 0xff0a}
|
|
const x = -1
|
|
want := []int{x, 0, x, 1, x, x, x, x, 2, 3, 4, 5, 6, 7, 8, 9}
|
|
for i, j := range want {
|
|
if j == x {
|
|
continue
|
|
}
|
|
m := bitmask(uint32(i))
|
|
if got := n.index(m); got != j {
|
|
t.Errorf("got %v, want %v", got, j)
|
|
}
|
|
}
|
|
}
|