aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/bolt/bench.go56
-rw-r--r--cmd/bolt/main.go28
2 files changed, 61 insertions, 23 deletions
diff --git a/cmd/bolt/bench.go b/cmd/bolt/bench.go
index 10a5599..fef8e54 100644
--- a/cmd/bolt/bench.go
+++ b/cmd/bolt/bench.go
@@ -2,6 +2,7 @@ package main
import (
"encoding/binary"
+ "encoding/json"
"errors"
"fmt"
"io/ioutil"
@@ -42,6 +43,11 @@ func Bench(options *BenchOptions) {
}
defer db.Close()
+ // Enable streaming stats.
+ if options.StatsInterval > 0 {
+ go printStats(db, options.StatsInterval)
+ }
+
// Start profiling for writes.
if options.ProfileMode == "rw" || options.ProfileMode == "w" {
benchStartProfiling(options)
@@ -73,9 +79,9 @@ func Bench(options *BenchOptions) {
}
// Print results.
- fmt.Printf("# 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.Println("")
+ fmt.Fprintf(os.Stderr, "# Write\t%v\t(%v/op)\t(%v op/sec)\n", results.WriteDuration, results.WriteOpDuration(), results.WriteOpsPerSecond())
+ fmt.Fprintf(os.Stderr, "# Read\t%v\t(%v/op)\t(%v op/sec)\n", results.ReadDuration, results.ReadOpDuration(), results.ReadOpsPerSecond())
+ fmt.Fprintln(os.Stderr, "")
}
// 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().
type BenchOptions struct {
- ProfileMode string
- WriteMode string
- ReadMode string
- Iterations int
- BatchSize int
- KeySize int
- ValueSize int
- CPUProfile string
- MemProfile string
- BlockProfile string
+ ProfileMode string
+ WriteMode string
+ ReadMode string
+ Iterations int
+ BatchSize int
+ KeySize int
+ ValueSize int
+ CPUProfile string
+ MemProfile string
+ BlockProfile string
+ StatsInterval time.Duration
}
// BenchResults represents the performance results of the benchmark.
diff --git a/cmd/bolt/main.go b/cmd/bolt/main.go
index cb2d47a..3558500 100644
--- a/cmd/bolt/main.go
+++ b/cmd/bolt/main.go
@@ -6,6 +6,7 @@ import (
"fmt"
"log"
"os"
+ "time"
"github.com/codegangsta/cli"
)
@@ -104,19 +105,26 @@ func NewApp() *cli.App {
&cli.StringFlag{Name: "cpuprofile", Usage: "CPU profile output path"},
&cli.StringFlag{Name: "memprofile", Usage: "Memory 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) {
+ statsInterval, err := time.ParseDuration(c.String("stats-interval"))
+ if err != nil {
+ fatal(err)
+ }
+
Bench(&BenchOptions{
- ProfileMode: c.String("profile-mode"),
- WriteMode: c.String("write-mode"),
- ReadMode: c.String("read-mode"),
- Iterations: c.Int("count"),
- BatchSize: c.Int("batch-size"),
- KeySize: c.Int("key-size"),
- ValueSize: c.Int("value-size"),
- CPUProfile: c.String("cpuprofile"),
- MemProfile: c.String("memprofile"),
- BlockProfile: c.String("blockprofile"),
+ ProfileMode: c.String("profile-mode"),
+ WriteMode: c.String("write-mode"),
+ ReadMode: c.String("read-mode"),
+ Iterations: c.Int("count"),
+ BatchSize: c.Int("batch-size"),
+ KeySize: c.Int("key-size"),
+ ValueSize: c.Int("value-size"),
+ CPUProfile: c.String("cpuprofile"),
+ MemProfile: c.String("memprofile"),
+ BlockProfile: c.String("blockprofile"),
+ StatsInterval: statsInterval,
})
},
}}