mirror of https://github.com/etcd-io/bbolt.git
commit
a18135e055
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -42,6 +43,11 @@ func Bench(options *BenchOptions) {
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
|
// Enable streaming stats.
|
||||||
|
if options.StatsInterval > 0 {
|
||||||
|
go printStats(db, options.StatsInterval)
|
||||||
|
}
|
||||||
|
|
||||||
// Start profiling for writes.
|
// Start profiling for writes.
|
||||||
if options.ProfileMode == "rw" || options.ProfileMode == "w" {
|
if options.ProfileMode == "rw" || options.ProfileMode == "w" {
|
||||||
benchStartProfiling(options)
|
benchStartProfiling(options)
|
||||||
|
@ -73,9 +79,9 @@ func Bench(options *BenchOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print results.
|
// Print results.
|
||||||
fmt.Printf("# Write\t%v\t(%v/op)\t(%v op/sec)\n", results.WriteDuration, results.WriteOpDuration(), results.WriteOpsPerSecond())
|
fmt.Fprintf(os.Stderr, "# Write\t%v\t(%v/op)\t(%v op/sec)\n", results.WriteDuration, results.WriteOpDuration(), results.WriteOpsPerSecond())
|
||||||
fmt.Printf("# Read\t%v\t(%v/op)\t(%v op/sec)\n", results.ReadDuration, results.ReadOpDuration(), results.ReadOpsPerSecond())
|
fmt.Fprintf(os.Stderr, "# Read\t%v\t(%v/op)\t(%v op/sec)\n", results.ReadDuration, results.ReadOpDuration(), results.ReadOpsPerSecond())
|
||||||
fmt.Println("")
|
fmt.Fprintln(os.Stderr, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes to the database.
|
// Writes to the database.
|
||||||
|
@ -233,18 +239,42 @@ func benchStopProfiling() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Continuously prints stats on the database at given intervals.
|
||||||
|
func printStats(db *bolt.DB, interval time.Duration) {
|
||||||
|
var prevStats = db.Stats()
|
||||||
|
var encoder = json.NewEncoder(os.Stdout)
|
||||||
|
|
||||||
|
for {
|
||||||
|
// Wait for the stats interval.
|
||||||
|
time.Sleep(interval)
|
||||||
|
|
||||||
|
// Retrieve new stats and find difference from previous iteration.
|
||||||
|
var stats = db.Stats()
|
||||||
|
var diff = stats.Sub(&prevStats)
|
||||||
|
|
||||||
|
// Print as JSON to STDOUT.
|
||||||
|
if err := encoder.Encode(diff); err != nil {
|
||||||
|
fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save stats for next iteration.
|
||||||
|
prevStats = stats
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BenchOptions represents the set of options that can be passed to Bench().
|
// BenchOptions represents the set of options that can be passed to Bench().
|
||||||
type BenchOptions struct {
|
type BenchOptions struct {
|
||||||
ProfileMode string
|
ProfileMode string
|
||||||
WriteMode string
|
WriteMode string
|
||||||
ReadMode string
|
ReadMode string
|
||||||
Iterations int
|
Iterations int
|
||||||
BatchSize int
|
BatchSize int
|
||||||
KeySize int
|
KeySize int
|
||||||
ValueSize int
|
ValueSize int
|
||||||
CPUProfile string
|
CPUProfile string
|
||||||
MemProfile string
|
MemProfile string
|
||||||
BlockProfile string
|
BlockProfile string
|
||||||
|
StatsInterval time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// BenchResults represents the performance results of the benchmark.
|
// BenchResults represents the performance results of the benchmark.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
)
|
)
|
||||||
|
@ -104,19 +105,26 @@ func NewApp() *cli.App {
|
||||||
&cli.StringFlag{Name: "cpuprofile", Usage: "CPU profile output path"},
|
&cli.StringFlag{Name: "cpuprofile", Usage: "CPU profile output path"},
|
||||||
&cli.StringFlag{Name: "memprofile", Usage: "Memory profile output path"},
|
&cli.StringFlag{Name: "memprofile", Usage: "Memory profile output path"},
|
||||||
&cli.StringFlag{Name: "blockprofile", Usage: "Block profile output path"},
|
&cli.StringFlag{Name: "blockprofile", Usage: "Block profile output path"},
|
||||||
|
&cli.StringFlag{Name: "stats-interval", Value: "0s", Usage: "Continuous stats interval"},
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
|
statsInterval, err := time.ParseDuration(c.String("stats-interval"))
|
||||||
|
if err != nil {
|
||||||
|
fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
Bench(&BenchOptions{
|
Bench(&BenchOptions{
|
||||||
ProfileMode: c.String("profile-mode"),
|
ProfileMode: c.String("profile-mode"),
|
||||||
WriteMode: c.String("write-mode"),
|
WriteMode: c.String("write-mode"),
|
||||||
ReadMode: c.String("read-mode"),
|
ReadMode: c.String("read-mode"),
|
||||||
Iterations: c.Int("count"),
|
Iterations: c.Int("count"),
|
||||||
BatchSize: c.Int("batch-size"),
|
BatchSize: c.Int("batch-size"),
|
||||||
KeySize: c.Int("key-size"),
|
KeySize: c.Int("key-size"),
|
||||||
ValueSize: c.Int("value-size"),
|
ValueSize: c.Int("value-size"),
|
||||||
CPUProfile: c.String("cpuprofile"),
|
CPUProfile: c.String("cpuprofile"),
|
||||||
MemProfile: c.String("memprofile"),
|
MemProfile: c.String("memprofile"),
|
||||||
BlockProfile: c.String("blockprofile"),
|
BlockProfile: c.String("blockprofile"),
|
||||||
|
StatsInterval: statsInterval,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Reference in New Issue