|
|
package db
import ( "bytes" "container/list" "encoding/binary" "fmt" "io/ioutil" "math/rand" "os" "path/filepath" "reflect" "testing" "time"
"github.com/guptarohit/asciigraph" )
type testKeyType int64
// Simple execution cmd
// go test -run=XXX -bench=. -benchmem -cpuprofile=cpu.out -memprofile=mem.out -timeout 20m -benchtime=1m
var valueLen = 256 var testSetSize = int64(10000000) var batchSize = 100
// parameters for drawing graph
var graphCountingPeriod = 10000 var graphWidth = 120 var graphHeigh = 20
var deviceType = "ssd"
func init() { rand.Seed(time.Now().Unix()) }
func int64ToBytes(i testKeyType) []byte { buf := make([]byte, 8) binary.BigEndian.PutUint64(buf, uint64(i)) return buf }
func printGraph(statics list.List) { if statics.Len() == 0 { return } // convert list to slice
var staticsSlice = make([]float64, statics.Len()) i := 0 for e := statics.Front(); e != nil; e = e.Next() { staticsSlice[i] = e.Value.(float64) i++ }
graph := asciigraph.Plot(staticsSlice, asciigraph.Width(graphWidth), asciigraph.Height(graphHeigh)) fmt.Println(graph) }
func dirSizeKB(path string) (int64, error) { var size int64 err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { if !info.IsDir() { size += info.Size() } return err }) return size / 1024, err }
func BenchmarkRandomWR(b *testing.B) {
// generate a common random data set
internal := map[testKeyType][]byte{} for i := 0; i < int(testSetSize); i++ { // generate a random value
token := make([]byte, valueLen) internal[testKeyType(i)] = token }
for dbType, dbConstructors := range dbImpls {
// create db
dbName := string(dbType) tmpDir, _ := ioutil.TempDir("", dbName) defer os.RemoveAll(tmpDir)
dbInstance, _ := dbConstructors(tmpDir) var numOfWrite int64 var idx testKeyType var statics list.List var startTime time.Time
fmt.Printf("[%s]\ntestset_size: %d\nkey_len: %d\nval_len: %d\n", dbName, testSetSize, reflect.TypeOf(idx).Size(), valueLen) fmt.Println("device type: ssd")
// write only
b.Run(dbName+"-write", func(b *testing.B) { var i int for i = 0; i < b.N; i++ { if i != 0 && i%graphCountingPeriod == 0 { startTime = time.Now() } idx = testKeyType((int64(rand.Int()) % testSetSize)) // pick a random key
rand.Read(internal[idx]) // generate a random data
dbInstance.Set( int64ToBytes(testKeyType(idx)), internal[idx], ) if i != 0 && i%graphCountingPeriod == 0 { endTime := time.Now().Sub(startTime).Seconds() statics.PushBack(endTime) } } numOfWrite += int64(i) })
printGraph(statics) statics.Init()
// read only
b.Run(dbName+"-read", func(b *testing.B) { for i := 0; i < b.N; i++ { if i != 0 && i%graphCountingPeriod == 0 { startTime = time.Now() } idx = testKeyType((int64(rand.Int()) % testSetSize)) originalVal := internal[idx]
retrievedVal := dbInstance.Get(int64ToBytes(testKeyType(idx)))
if len(retrievedVal) != 0 { if len(retrievedVal) != valueLen { b.Errorf("Expected length %X for %v, got %X", valueLen, idx, len(retrievedVal)) break } else if !bytes.Equal(retrievedVal, originalVal) { b.Errorf("Expected %v for %v, got %v", originalVal, idx, retrievedVal) break } }
if i != 0 && i%graphCountingPeriod == 0 { endTime := time.Now().Sub(startTime).Seconds() statics.PushBack(endTime) } } })
printGraph(statics) statics.Init()
// write and read
b.Run(dbName+"-write-read", func(b *testing.B) { var i int for i = 0; i < b.N; i++ { if i != 0 && i%graphCountingPeriod == 0 { startTime = time.Now() } idx = testKeyType(int64(rand.Int()) % testSetSize) // pick a random key
rand.Read(internal[idx]) // generate a random data
dbInstance.Set( int64ToBytes(testKeyType(idx)), internal[idx], )
originalVal := internal[idx]
retrievedVal := dbInstance.Get(int64ToBytes(testKeyType(idx)))
if len(retrievedVal) != 0 { if len(retrievedVal) != valueLen { b.Errorf("Expected length %X for %v, got %X", valueLen, idx, len(retrievedVal)) break } else if !bytes.Equal(retrievedVal, originalVal) { b.Errorf("Expected %v for %v, got %v", originalVal, idx, retrievedVal) break } }
if i != 0 && i%graphCountingPeriod == 0 { endTime := time.Now().Sub(startTime).Seconds() statics.PushBack(endTime) } } numOfWrite += int64(i) })
printGraph(statics) statics.Init()
// close
dbInstance.Close()
size, err := dirSizeKB(tmpDir) if err != nil { fmt.Println(err) } else { fmt.Printf("* Total size of %s db: %v kb, Size of 1 write: %v byte\n", dbName, size, size*1024/numOfWrite) } } }
func BenchmarkRandomBatchWR(b *testing.B) {
// generate a common random data set
internal := map[testKeyType][]byte{} for i := 0; i < int(testSetSize); i++ { // generate a random value
token := make([]byte, valueLen) internal[testKeyType(i)] = token }
for dbType, dbConstructors := range dbImpls {
// create db
dbName := string(dbType) tmpDir, _ := ioutil.TempDir("", dbName) defer os.RemoveAll(tmpDir)
dbInstance, _ := dbConstructors(tmpDir) var numOfWrite int64 var idx testKeyType var statics list.List var startTime time.Time
fmt.Printf("[%s]\ntestset_size: %d\nkey_len: %d\nval_len: %d\n", dbName, testSetSize, reflect.TypeOf(idx).Size(), valueLen) fmt.Println("device type: " + deviceType) fmt.Printf("batch size: %d\n", batchSize)
// write only
b.Run(dbName+"-batch-write", func(b *testing.B) { var i int
for i = 0; i < b.N; i++ { if i != 0 && i%graphCountingPeriod == 0 { startTime = time.Now() } tx := dbInstance.NewTx()
for j := 0; j < batchSize; j++ { idx = testKeyType((int64(rand.Int()) % testSetSize)) // pick a random key
rand.Read(internal[idx]) // generate a random data
tx.Set( int64ToBytes(testKeyType(idx)), internal[idx], ) } tx.Commit() if i != 0 && i%graphCountingPeriod == 0 { endTime := time.Now().Sub(startTime).Seconds() statics.PushBack(endTime) } } numOfWrite += int64(i) })
// print a graph
printGraph(statics) statics.Init()
// read only
b.Run(dbName+"-read", func(b *testing.B) { for i := 0; i < b.N; i++ { if i != 0 && i%graphCountingPeriod == 0 { startTime = time.Now() }
idx = testKeyType((int64(rand.Int()) % testSetSize)) originalVal := internal[idx]
retrievedVal := dbInstance.Get(int64ToBytes(testKeyType(idx)))
if len(retrievedVal) != 0 { if len(retrievedVal) != valueLen { b.Errorf("Expected length %X for %v, got %X", valueLen, idx, len(retrievedVal)) break } else if !bytes.Equal(retrievedVal, originalVal) { b.Errorf("Expected %v for %v, got %v", originalVal, idx, retrievedVal) break } } if i != 0 && i%graphCountingPeriod == 0 { endTime := time.Now().Sub(startTime).Seconds() statics.PushBack(endTime) } } })
// close
dbInstance.Close()
printGraph(statics)
size, err := dirSizeKB(tmpDir) if err != nil { fmt.Println(err) } else { fmt.Printf("* Total size of %s db: %v kb, Size of 1 write: %v byte\n", dbName, size, size*1024/numOfWrite) } } }
/* [Refined Test Result] goos: windows goarch: amd64 pkg: github.com/aergoio/aergo-lib/db
[badgerdb-ssd-single] testset_size: 10000000 key_len: 8 val_len: 256 device type: ssd BenchmarkRandomWR/badgerdb-write-12 30000000 29536 ns/op 4983 B/op 84 allocs/op BenchmarkRandomWR/badgerdb-read-12 20000000 47739 ns/op 13154 B/op 60 allocs/op BenchmarkRandomWR/badgerdb-write-read-12 20000000 41990 ns/op 10317 B/op 140 allocs/op * Total size of badgerdb db: 14544473 kb, Size of 1 write: 286 byte
[leveldb-ssd-single] testset_size: 10000000 key_len: 8 val_len: 256 device type: ssd BenchmarkRandomWR/leveldb-write-12 1000000 1006445 ns/op 532 B/op 5 allocs/op BenchmarkRandomWR/leveldb-read-12 50000000 18941 ns/op 1160 B/op 17 allocs/op BenchmarkRandomWR/leveldb-write-read-12 1000000 986440 ns/op 1272 B/op 11 allocs/op * Total size of leveldb db: 567386 kb, Size of 1 write: 250 byte
[badgerdb-ssd-batch100] testset_size: 10000000 key_len: 8 val_len: 256 device type: ssd batch size: 100 BenchmarkRandomBatchWR/badgerdb-batch-write-12 2000000 612737 ns/op 383751 B/op 4576 allocs/op BenchmarkRandomBatchWR/badgerdb-read-12 20000000 53298 ns/op 22177 B/op 71 allocs/op * Total size of badgerdb db: 74546912 kb, Size of 1 write: 25359 byte
[leveldb-ssd-batch100] testset_size: 10000000 key_len: 8 val_len: 256 device type: ssd batch size: 100 BenchmarkRandomBatchWR/leveldb-batch-write-12 300000 6778458 ns/op 127466 B/op 399 allocs/op BenchmarkRandomBatchWR/leveldb-read-12 5000000 141176 ns/op 4547 B/op 34 allocs/op * Total size of leveldb db: 2540271 kb, Size of 1 write: 8388 byte
[badgerdb-ssd-batch1000] testset_size: 10000000 key_len: 8 val_len: 256 device type: ssd batch size: 1000 BenchmarkRandomBatchWR1000/badgerdb-batch-write-12 200000 5507060 ns/op 3504344 B/op 42743 allocs/op BenchmarkRandomBatchWR1000/badgerdb-read-12 20000000 52636 ns/op 21867 B/op 73 allocs/op * Total size of badgerdb db: 51315516 kb, Size of 1 write: 250103 byte
[leveldb-ssd-batch100] testset_size: 10000000 key_len: 8 val_len: 256 device type: ssd batch size: 1000 BenchmarkRandomBatchWR1000/leveldb-batch-write-12 20000 70431430 ns/op 1081956 B/op 3906 allocs/op BenchmarkRandomBatchWR1000/leveldb-read-12 5000000 138074 ns/op 4194 B/op 33 allocs/op * Total size of leveldb db: 2529393 kb, Size of 1 write: 86046 byte
[badgerdb-hdd-single] testset_size: 10000000 key_len: 8 val_len: 256 device type: hdd BenchmarkHddRandomWR/badgerdb-write-12 30000000 27901 ns/op 4809 B/op 82 allocs/op BenchmarkHddRandomWR/badgerdb-read-12 20000000 45765 ns/op 14321 B/op 68 allocs/op BenchmarkHddRandomWR/badgerdb-write-read-12 20000000 39404 ns/op 8693 B/op 124 allocs/op * Total size of badgerdb db: 14697136 kb, Size of 1 write: 289 byte
[leveldb-hdd-single] testset_size: 10000000 key_len: 8 val_len: 256 device type: hdd BenchmarkHddRandomWR/leveldb-write-12 50000 20975160 ns/op 551 B/op 4 allocs/op BenchmarkHddRandomWR/leveldb-read-12 100000000 10375 ns/op 988 B/op 14 allocs/op BenchmarkHddRandomWR/leveldb-write-read-12 50000 21144257 ns/op 994 B/op 9 allocs/op * Total size of leveldb db: 31940 kb, Size of 1 write: 272 byte
[badgerdb-hdd-batch100] testset_size: 10000000 key_len: 8 val_len: 256 device type: hdd batch size: 100 BenchmarkHddRandomBatchWR/badgerdb-batch-write-12 1000000 675351 ns/op 329398 B/op 4007 allocs/op BenchmarkHddRandomBatchWR/badgerdb-read-12 10000000 87933 ns/op 22713 B/op 85 allocs/op * Total size of badgerdb db: 24285947 kb, Size of 1 write: 24620 byte
[leveldb-hdd-batch100] testset_size: 10000000 key_len: 8 val_len: 256 device type: hdd batch size: 100 BenchmarkHddRandomBatchWR/leveldb-batch-write-12 30000 45769594 ns/op 136783 B/op 399 allocs/op BenchmarkHddRandomBatchWR/leveldb-read-12 20000000 30579 ns/op 3386 B/op 19 allocs/op * Total size of leveldb db: 878403 kb, Size of 1 write: 22430 byte
[badgerdb-hdd-batch1000] testset_size: 10000000 key_len: 8 val_len: 256 device type: hdd batch size: 1000 BenchmarkHddRandomBatchWR1000/badgerdb-batch-write-12 200000 6599637 ns/op 3724911 B/op 43392 allocs/op BenchmarkHddRandomBatchWR1000/badgerdb-read-12 10000000 99201 ns/op 31710 B/op 105 allocs/op * Total size of badgerdb db: 51157857 kb, Size of 1 write: 249335 byte
[leveldb-hdd-batch1000] testset_size: 10000000 key_len: 8 val_len: 256 device type: hdd batch size: 1000 BenchmarkHddRandomBatchWR1000/leveldb-batch-write-12 10000 209360868 ns/op 1027546 B/op 3363 allocs/op BenchmarkHddRandomBatchWR1000/leveldb-read-12 10000000 87929 ns/op 3971 B/op 29 allocs/op * Total size of leveldb db: 1689120 kb, Size of 1 write: 171236 byte
PASS ok github.com/aergoio/aergo-lib/db 33617.451s */
|