+268
@@ -0,0 +1,268 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package btree
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const benchmarkTreeSize = 10000
|
||||
|
||||
var degrees = []int{2, 8, 32, 64}
|
||||
|
||||
func BenchmarkInsert(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
i := 0
|
||||
for i < b.N {
|
||||
tr := New(d, less)
|
||||
for _, m := range insertP {
|
||||
tr.Set(m.Key, m.Value)
|
||||
i++
|
||||
if i >= b.N {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDeleteInsert(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
tr := New(d, less)
|
||||
for _, m := range insertP {
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
m := insertP[i%benchmarkTreeSize]
|
||||
tr.Delete(m.Key)
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDeleteInsertCloneOnce(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
tr := New(d, less)
|
||||
for _, m := range insertP {
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
tr = tr.Clone()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
m := insertP[i%benchmarkTreeSize]
|
||||
tr.Delete(m.Key)
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDeleteInsertCloneEachTime(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
tr := New(d, less)
|
||||
for _, m := range insertP {
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
tr = tr.Clone()
|
||||
m := insertP[i%benchmarkTreeSize]
|
||||
tr.Delete(m.Key)
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDelete(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
removeP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
i := 0
|
||||
for i < b.N {
|
||||
b.StopTimer()
|
||||
tr := New(d, less)
|
||||
for _, v := range insertP {
|
||||
tr.Set(v.Key, v.Value)
|
||||
}
|
||||
b.StartTimer()
|
||||
for _, m := range removeP {
|
||||
tr.Delete(m.Key)
|
||||
i++
|
||||
if i >= b.N {
|
||||
return
|
||||
}
|
||||
}
|
||||
if tr.Len() > 0 {
|
||||
panic(tr.Len())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGet(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
getP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
i := 0
|
||||
for i < b.N {
|
||||
b.StopTimer()
|
||||
tr := New(d, less)
|
||||
for _, v := range insertP {
|
||||
tr.Set(v.Key, v.Value)
|
||||
}
|
||||
b.StartTimer()
|
||||
for _, m := range getP {
|
||||
tr.Get(m.Key)
|
||||
i++
|
||||
if i >= b.N {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetWithIndex(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
getP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
i := 0
|
||||
for i < b.N {
|
||||
b.StopTimer()
|
||||
tr := New(d, less)
|
||||
for _, v := range insertP {
|
||||
tr.Set(v.Key, v.Value)
|
||||
}
|
||||
b.StartTimer()
|
||||
for _, m := range getP {
|
||||
tr.GetWithIndex(m.Key)
|
||||
i++
|
||||
if i >= b.N {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGetCloneEachTime(b *testing.B) {
|
||||
insertP := perm(benchmarkTreeSize)
|
||||
getP := perm(benchmarkTreeSize)
|
||||
for _, d := range degrees {
|
||||
b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
|
||||
i := 0
|
||||
for i < b.N {
|
||||
b.StopTimer()
|
||||
tr := New(d, less)
|
||||
for _, m := range insertP {
|
||||
tr.Set(m.Key, m.Value)
|
||||
}
|
||||
b.StartTimer()
|
||||
for _, m := range getP {
|
||||
tr = tr.Clone()
|
||||
tr.Get(m.Key)
|
||||
i++
|
||||
if i >= b.N {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFind(b *testing.B) {
|
||||
for _, d := range degrees {
|
||||
var items []item
|
||||
for i := 0; i < 2*d; i++ {
|
||||
items = append(items, item{i, i})
|
||||
}
|
||||
b.Run(fmt.Sprintf("size=%d", len(items)), func(b *testing.B) {
|
||||
for _, alg := range []struct {
|
||||
name string
|
||||
fun func(Key, []item) (int, bool)
|
||||
}{
|
||||
{"binary", findBinary},
|
||||
{"linear", findLinear},
|
||||
} {
|
||||
b.Run(alg.name, func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := 0; j < len(items); j++ {
|
||||
alg.fun(items[j].key, items)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func findBinary(k Key, s []item) (int, bool) {
|
||||
i := sort.Search(len(s), func(i int) bool { return less(k, s[i].key) })
|
||||
// i is the smallest index of s for which key.Less(s[i].Key), or len(s).
|
||||
if i > 0 && !less(s[i-1], k) {
|
||||
return i - 1, true
|
||||
}
|
||||
return i, false
|
||||
}
|
||||
|
||||
func findLinear(k Key, s []item) (int, bool) {
|
||||
var i int
|
||||
for i = 0; i < len(s); i++ {
|
||||
if less(k, s[i].key) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if i > 0 && !less(s[i-1].key, k) {
|
||||
return i - 1, true
|
||||
}
|
||||
return i, false
|
||||
}
|
||||
|
||||
type byInts []item
|
||||
|
||||
func (a byInts) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a byInts) Less(i, j int) bool {
|
||||
return a[i].key.(int) < a[j].key.(int)
|
||||
}
|
||||
|
||||
func (a byInts) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
Reference in New Issue
Block a user