Last active
August 29, 2015 13:56
-
-
Save nobonobo/8835859 to your computer and use it in GitHub Desktop.
golang KVS Insertion Benchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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