Add benchmarks.

master
Ben Johnson 2014-03-04 13:02:17 -07:00
parent 3a1b152562
commit 64fcacedfa
5 changed files with 106 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.prof
*.test

View File

@ -14,6 +14,10 @@ cover: fmt
go tool cover -html=$(COVERPROFILE)
rm $(COVERPROFILE)
cpuprofile: fmt
@go test -c
@./bolt.test -test.v -test.run="^X" -test.bench=$(BENCH) -test.cpuprofile cpu.prof
fmt:
@go fmt ./...
@ -25,4 +29,4 @@ test: fmt
@echo "=== RACE DETECTOR ==="
@go test -v -race -test.run=Parallel
.PHONY: bench cloc cover fmt test
.PHONY: bench cloc cover cpuprofile fmt memprofile test

View File

@ -3,8 +3,10 @@ package bolt
import (
"io"
"io/ioutil"
"math/rand"
"os"
"strconv"
"strings"
"syscall"
"testing"
"time"
@ -341,6 +343,29 @@ func TestDBString(t *testing.T) {
assert.Equal(t, db.GoString(), `bolt.DB{path:"/tmp/foo"}`)
}
// Benchmark the performance of single put transactions in random order.
func BenchmarkDBPutSequential(b *testing.B) {
value := []byte(strings.Repeat("0", 64))
withOpenDB(func(db *DB, path string) {
db.CreateBucket("widgets")
for i := 0; i < b.N; i++ {
db.Put("widgets", []byte(strconv.Itoa(i)), value)
}
})
}
// Benchmark the performance of single put transactions in random order.
func BenchmarkDBPutRandom(b *testing.B) {
indexes := rand.Perm(b.N)
value := []byte(strings.Repeat("0", 64))
withOpenDB(func(db *DB, path string) {
db.CreateBucket("widgets")
for i := 0; i < b.N; i++ {
db.Put("widgets", []byte(strconv.Itoa(indexes[i])), value)
}
})
}
// withDB executes a function with a database reference.
func withDB(fn func(*DB, string)) {
f, _ := ioutil.TempFile("", "bolt-")

View File

@ -1,6 +1,8 @@
package bolt
import (
"math/rand"
"strconv"
"strings"
"testing"
@ -140,3 +142,40 @@ func TestRWTransactionDeleteBucketNotFound(t *testing.T) {
assert.Equal(t, err, ErrBucketNotFound)
})
}
// Benchmark the performance of bulk put transactions in random order.
func BenchmarkRWTransactionPutRandom(b *testing.B) {
indexes := rand.Perm(b.N)
value := []byte(strings.Repeat("0", 64))
withOpenDB(func(db *DB, path string) {
db.CreateBucket("widgets")
var txn *RWTransaction
var bucket *Bucket
for i := 0; i < b.N; i++ {
if i%1000 == 0 {
if txn != nil {
txn.Commit()
}
txn, _ = db.RWTransaction()
bucket = txn.Bucket("widgets")
}
bucket.Put([]byte(strconv.Itoa(indexes[i])), value)
}
txn.Commit()
})
}
// Benchmark the performance of bulk put transactions in sequential order.
func BenchmarkRWTransactionPutSequential(b *testing.B) {
value := []byte(strings.Repeat("0", 64))
withOpenDB(func(db *DB, path string) {
db.CreateBucket("widgets")
db.Do(func(txn *RWTransaction) error {
bucket := txn.Bucket("widgets")
for i := 0; i < b.N; i++ {
bucket.Put([]byte(strconv.Itoa(i)), value)
}
return nil
})
})
}

View File

@ -2,8 +2,11 @@ package bolt
import (
"fmt"
"math/rand"
"os"
"sort"
"strconv"
"strings"
"testing"
"testing/quick"
@ -228,3 +231,35 @@ func TestTransactionCursorIterateReverse(t *testing.T) {
}
fmt.Fprint(os.Stderr, "\n")
}
// Benchmark the performance iterating over a cursor.
func BenchmarkTransactionCursor(b *testing.B) {
indexes := rand.Perm(b.N)
value := []byte(strings.Repeat("0", 64))
withOpenDB(func(db *DB, path string) {
// Write data to bucket.
db.CreateBucket("widgets")
db.Do(func(txn *RWTransaction) error {
bucket := txn.Bucket("widgets")
for i := 0; i < b.N; i++ {
bucket.Put([]byte(strconv.Itoa(indexes[i])), value)
}
return nil
})
b.ResetTimer()
// Iterate over bucket using cursor.
db.With(func(txn *Transaction) error {
count := 0
c := txn.Bucket("widgets").Cursor()
for k, _ := c.First(); k != nil; k, _ = c.Next() {
count++
}
if count != b.N {
b.Fatalf("wrong count: %d; expected: %d", count, b.N)
}
return nil
})
})
}