Skip to content

Instantly share code, notes, and snippets.

@nobonobo
Last active August 29, 2015 13:56
Show Gist options
  • Select an option

  • Save nobonobo/8835859 to your computer and use it in GitHub Desktop.

Select an option

Save nobonobo/8835859 to your computer and use it in GitHub Desktop.
golang KVS Insertion Benchmark
package main
import (
"database/sql"
"encoding/gob"
"fmt"
_ "github.com/mattn/go-sqlite3"
"github.com/nobonobo/unqlitego"
"github.com/peterbourgon/diskv"
"github.com/steveyen/gkvlite"
"github.com/syndtr/goleveldb/leveldb"
"os"
"testing"
)
const create_table = `
create table foo (id text not null primary key, name text);
delete from foo;
PRAGMA SYNCHRONOUS = OFF;
`
func BenchmarkUnQLite1(b *testing.B) {
os.Remove("./db.unqlite")
db, err := unqlitego.NewDatabase("./db.unqlite")
if err != nil {
b.Fatal(err)
}
defer db.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := db.Store([]byte(fmt.Sprintf("key:%012d", i)), []byte(fmt.Sprintf("val:%012d", i)))
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkUnQLite1000(b *testing.B) {
os.Remove("./db.unqlite")
db, err := unqlitego.NewDatabase("./db.unqlite")
if err != nil {
b.Fatal(err)
}
defer db.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ {
err := db.Store([]byte(fmt.Sprintf("key:%012d", i*1000+j)), []byte(fmt.Sprintf("val:%012d", i*1000+j)))
if err != nil {
b.Fatal(i, j, err)
}
}
}
}
func BenchmarkSQLite1(b *testing.B) {
os.Remove("./db.sqlite")
db, err := sql.Open("sqlite3", "./db.sqlite")
if err != nil {
b.Fatal(err)
}
defer db.Close()
_, err = db.Exec(create_table)
if err != nil {
b.Fatal(err)
}
stmt, err := db.Prepare("insert into foo(id, name) values(?, ?)")
defer stmt.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err = stmt.Exec(fmt.Sprintf("key:%012d", i), fmt.Sprintf("val:%012d", i))
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkSQLite1000(b *testing.B) {
os.Remove("./db.sqlite")
db, err := sql.Open("sqlite3", "./db.sqlite")
if err != nil {
b.Fatal(err)
}
defer db.Close()
_, err = db.Exec(create_table)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
tx, err := db.Begin()
if err != nil {
b.Fatal(err)
}
stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")
defer stmt.Close()
for j := 0; j < 1000; j++ {
_, err = stmt.Exec(fmt.Sprintf("key:%012d", i*1000+j), fmt.Sprintf("val:%012d", i*1000+j))
if err != nil {
b.Fatal(err)
}
}
tx.Commit()
}
}
func BenchmarkGKVLite1(b *testing.B) {
os.Remove("./db.kvlite")
fp, err := os.Create("./db.kvlite")
if err != nil {
b.Fatal(err)
}
db, err := gkvlite.NewStore(fp)
if err != nil {
b.Fatal(err)
}
defer db.Close()
collection := db.SetCollection("table", nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
collection.Set([]byte(fmt.Sprintf("key:%012d", i)), []byte(fmt.Sprintf("val:%012d", i)))
}
db.Flush()
}
func BenchmarkGKVLite1000(b *testing.B) {
os.Remove("./db.kvlite")
fp, err := os.Create("./db.kvlite")
if err != nil {
b.Fatal(err)
}
db, err := gkvlite.NewStore(fp)
if err != nil {
b.Fatal(err)
}
defer db.Close()
collection := db.SetCollection("table", nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ {
collection.Set([]byte(fmt.Sprintf("key:%012d", i*1000+j)), []byte(fmt.Sprintf("val:%012d", i*1000+j)))
}
}
db.Flush()
}
type Sample struct {
Key string
Value interface{}
}
func BenchmarkGob1(b *testing.B) {
os.Remove("./db.gob")
fp, err := os.Create("./db.gob")
if err != nil {
b.Fatal(err)
}
defer fp.Close()
enc := gob.NewEncoder(fp)
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := enc.Encode(&Sample{Key: fmt.Sprintf("key:%012d", i), Value: fmt.Sprintf("val:%012d", i)})
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkGob1000(b *testing.B) {
os.Remove("./db.gob")
fp, err := os.Create("./db.gob")
if err != nil {
b.Fatal(err)
}
defer fp.Close()
enc := gob.NewEncoder(fp)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ {
err := enc.Encode(&Sample{Key: fmt.Sprintf("key:%012d", i*1000+j), Value: fmt.Sprintf("val:%012d", i*1000+j)})
if err != nil {
b.Fatal(err)
}
}
}
}
func BenchmarkBin1(b *testing.B) {
os.Remove("./db.gob")
fp, err := os.Create("./db.bin")
if err != nil {
b.Fatal(err)
}
defer fp.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := fmt.Fprintf(fp, "key:%012[1]d,val:%012[1]d\n", i)
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkBin1000(b *testing.B) {
os.Remove("./db.gob")
fp, err := os.Create("./db.bin")
if err != nil {
b.Fatal(err)
}
defer fp.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ {
_, err := fmt.Fprintf(fp, "key:%012[1]d,val:%012[1]d\n", i*1000+j)
if err != nil {
b.Fatal(err)
}
}
}
}
func BenchmarkDiskv1(b *testing.B) {
os.RemoveAll("./diskv")
d := diskv.New(diskv.Options{
BasePath: "./diskv",
Transform: func(s string) []string { return []string{} },
CacheSizeMax: 1024 * 1024,
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := d.Write(fmt.Sprintf("key%012d", i), []byte(fmt.Sprintf("val:%012d", i)))
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkDiskv1000(b *testing.B) {
os.RemoveAll("./diskv")
d := diskv.New(diskv.Options{
BasePath: "./diskv",
Transform: func(s string) []string { return []string{} },
CacheSizeMax: 1024 * 1024,
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ {
err := d.Write(fmt.Sprintf("key%012d", i*1000+j), []byte(fmt.Sprintf("val:%012d", i*1000+j)))
if err != nil {
b.Fatal(err)
}
}
}
}
func BenchmarkLeveldb1(b *testing.B) {
os.RemoveAll("./leveldb")
db, err := leveldb.OpenFile("./leveldb", nil)
if err != nil {
b.Fatal(err)
}
defer db.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := db.Put([]byte(fmt.Sprintf("key:%012d", i)), []byte(fmt.Sprintf("val:%012d", i)), nil)
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkLeveldb1000(b *testing.B) {
os.RemoveAll("./leveldb")
db, err := leveldb.OpenFile("./leveldb", nil)
if err != nil {
b.Fatal(err)
}
defer db.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ {
err := db.Put([]byte(fmt.Sprintf("key:%012d", i*1000+j)), []byte(fmt.Sprintf("val:%012d", i*1000+j)), nil)
if err != nil {
b.Fatal(err)
}
}
}
}
# macbook-air2011mid
$ go test -bench . -benchmem
BenchmarkUnQLite1 200000 8600 ns/op 96 B/op 4 allocs/op
BenchmarkUnQLite1000 500 8352548 ns/op 96000 B/op 4000 allocs/op
BenchmarkSQLite1 2000 1322385 ns/op 319 B/op 12 allocs/op
BenchmarkSQLite1000 100 17190212 ns/op 243590 B/op 10024 allocs/op
BenchmarkGKVLite1 100000 29387 ns/op 378 B/op 9 allocs/op
BenchmarkGKVLite1000 100 26947231 ns/op 290018 B/op 9015 allocs/op
BenchmarkGob1 200000 10437 ns/op 248 B/op 6 allocs/op
BenchmarkGob1000 200 10824993 ns/op 247479 B/op 6035 allocs/op
BenchmarkBin1 500000 4308 ns/op 0 B/op 0 allocs/op
BenchmarkBin1000 500 4552521 ns/op 0 B/op 0 allocs/op
BenchmarkDiskv1 10000 244554 ns/op 716 B/op 22 allocs/op
BenchmarkDiskv1000 10 226839974 ns/op 721927 B/op 22144 allocs/op
BenchmarkLeveldb1 100000 22236 ns/op 810 B/op 9 allocs/op
BenchmarkLeveldb1000 100 22728302 ns/op 810688 B/op 9012 allocs/op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment