rosedblabs / rosedb

Lightweight, fast and reliable key/value storage engine based on Bitcask.
https://rosedblabs.github.io
Apache License 2.0
4.58k stars 632 forks source link

Optimize memory usage #287

Closed roseduan closed 10 months ago

roseduan commented 1 year ago
package kv

import (
    "fmt"
    "github.com/cockroachdb/pebble"
    "github.com/rosedblabs/rosedb/v2"
    "math"
    "math/rand"
    "sync"
    "testing"
    "time"
)

var pebbledb *pebble.DB
var rdb *rosedb.DB

func init() {
    var err error
    opt := &pebble.Options{BytesPerSync: math.MaxInt, WALBytesPerSync: math.MaxInt}
    pebbledb, err = pebble.Open("/tmp/pebble-bench", opt)
    if err != nil {
        panic(err)
    }

    options := rosedb.DefaultOptions
    options.DirPath = "/tmp/rosedb-bench"
    rdb, err = rosedb.Open(options)
    if err != nil {
        panic(err)
    }
}

func BenchmarkPebble_Get(b *testing.B) {
    for i := 0; i < 1000000; i++ {
        pebbledb.Set(GetTestKey(i), RandomValue(128), &pebble.WriteOptions{Sync: false})
    }

    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _, _, err := pebbledb.Get(GetTestKey(i))
        if err != nil && err != pebble.ErrNotFound {
            panic(err)
        }
    }
}

func BenchmarkRoseDB_Get(b *testing.B) {
    for i := 0; i < 1000000; i++ {
        rdb.Put(GetTestKey(i), RandomValue(128))
    }

    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        _, err := rdb.Get(GetTestKey(i))
        if err != nil && err != rosedb.ErrKeyNotFound {
            panic(err)
        }
    }
}

var (
    lock    = sync.Mutex{}
    randStr = rand.New(rand.NewSource(time.Now().Unix()))
    letters = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
)

// GetTestKey get formated key, for test only
func GetTestKey(i int) []byte {
    return []byte(fmt.Sprintf("rosedb-test-key-%09d", i))
}

// RandomValue generate random value, for test only
func RandomValue(n int) []byte {
    b := make([]byte, n)
    for i := range b {
        lock.Lock()
        b[i] = letters[randStr.Intn(len(letters))]
        lock.Unlock()
    }
    return []byte("rosedb-test-value-" + string(b))
}

Run RoseDB:

go test -v -bench=BenchmarkRoseDB_Get -memprofile rosedb.out

Run Pebble:

go test -v -bench=BenchmarkPebble_Get -memprofile pebble.out

Analyze:

go tool pprof rosedb.out
go tool pprof pebble.out
image image