a go ordered map that supports custom sorting rule
go get github.com/pigfu/orderedmapvar (
N=int64(100000)
)
funcBenchmarkNew(b*testing.B) {
m:=New[int64, int]()
fori:=0; i<b.N; i++ {
m.Set(rand.Int63n(N), i)
}
}
funccmp(k1, k2int64) int {
ifk1<k2 {
return-1
}
ifk1>k2 {
return1
}
return0
}
funcBenchmarkNewCmp(b*testing.B) {
m:=NewCmp[int64, int](cmp)
fori:=0; i<b.N; i++ {
m.Set(rand.Int63n(N), i)
}
}
funccmpVal(v1, v2int) int {
ifv1<v2 {
return-1
}
ifv1>v2 {
return1
}
return0
}
funcBenchmarkNewCmpVal(b*testing.B) {
m:=NewCmpVal[int64, int](cmpVal)
fori:=0; i<b.N; i++ {
m.Set(rand.Int63n(N), i)
}
}goos: windows
goarch: amd64
pkg: github.com/pigfu/orderedmap
cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
BenchmarkNew-12 17014821 71.68 ns/op
BenchmarkNewCmp-12 14796138 76.79 ns/op
BenchmarkNewCmpVal-12 2105310 576.1 ns/op
PASS
ok github.com/pigfu/orderedmap 6.172s- the New function use double linked list,so Set and Del is O(1).
- the NewCmp function use skip list,so Set is O(logN) (but update is O(1)) and Del is O(1),because every level is double linked list.
- the NewCmpValue function also use skip list,Set is O(logN) (but update is O(logN),because compare value need firstly delete key and then insert) and Del is O(1).
package main
import (
. "github.com/pigfu/orderedmap""fmt"
)
var (
insertKeys= []int{9, 2, 6, 8, 599, 4, 9, 10, 5, 8, 100}
deleteKeys= []int{5, 8, 9, 7, 999}
)
//key order by insert functestNew() {
m:=New[int, int]()
fori, k:=rangeinsertKeys {
m.Set(k, i)
}
foriter:=m.Iter(); iter.Next(); {
fmt.Println(iter.KV())
}
fmt.Println("------testNew------")
for_, k:=rangedeleteKeys {
m.Del(k)
}
foriter:=m.Iter(); iter.Next(); {
fmt.Println(iter.KV())
}
}
funccmp(k1, k2int) int {
ifk1<k2 {
return-1
}
ifk1>k2 {
return1
}
return0
}
// compare with keyfunctestNewCmp() {
m:=NewCmp[int, int32](cmp)
fori, k:=rangeinsertKeys {
m.Set(k, int32(i))
}
foriter:=m.Iter(); iter.Next(); {
fmt.Println(iter.KV())
}
fmt.Println("------testNewCmp------")
for_, k:=rangedeleteKeys {
m.Del(k)
}
foriter:=m.Iter(); iter.Next(); {
fmt.Println(iter.KV())
}
}
funccmpVal(v1, v2int32) int {
ifv1<v2 {
return-1
}
ifv1>v2 {
return1
}
return0
}
//compare with valuefunctestNewCmpVal() {
m:=NewCmpVal[int, int32](cmpVal)
fori, k:=rangeinsertKeys {
m.Set(k, int32(i))
}
foriter:=m.Iter(); iter.Next(); {
fmt.Println(iter.KV())
}
fmt.Println("------testNewCmpVal------")
for_, k:=rangedeleteKeys {
m.Del(k)
}
foriter:=m.Iter(); iter.Next(); {
fmt.Println(iter.KV())
}
}
funcmain() {
testNew()
testNewCmp()
testNewCmpVal()
}