Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,24 @@ Same as `write`, but in batches rather than singular puts. Perform concurrent `b
- `--concurrency`: default 1
- `--valueSize`: size of value, as a number in bytes or string with unit (e.g. `--valueSize 1kb`)

### `self-distribution`

_Not a benchmark, but a temporary cheat to reuse the tooling we have here to test (and visualize) some of the internals. Needs a valid `target` argument, same as real benchmarks, although that argument is not actually used._

Generate keys with a certain order and probability distribution. Options:

- `-n`: amount of keys to generate, default 5e3
- Other options are passed to [`keyspace`](https://github.com/vweevers/keyspace)

Example:

```
level-bench run self-distribution memdown -b [--distribution zipfian --skew 1]
level-bench run self-distribution memdown -b [--distribution zipfian --skew=-1]
level-bench run self-distribution memdown -b [--keys seq]
level-bench plot self-distribution
```

<!-- ### Other ideas

- Write batches in different sizes (feature: define a matrix)
Expand Down
1 change: 1 addition & 0 deletions benchmarks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ exports['write-random'] = require('./write-random')
exports['write-sorted'] = require('./write-sorted')

exports['batch-put'] = require('./batch-put')
exports['self-distribution'] = require('./self-distribution')
49 changes: 49 additions & 0 deletions benchmarks/self-distribution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict'

const keyspace = require('keyspace')

exports.defaults = {
benchmark: {
n: 5e3
}
}

exports.plot = require('./self-distribution.plot')

exports.run = function (factory, stream, options) {
stream.write('Step, Key, Frequency\n')

const generator = keyspace(options.n, Object.assign({}, options, {
keyAsNumber: true
}))

let step = 0

const frequencies = new Array(options.n).fill(0)
const keys = new Array(options.n).fill(0)

while (step < options.n) {
const key = generator.key(step)

frequencies[key]++
keys[step++] = key

if (step % 1000 === 0) {
console.log('%d %d%', step, Math.round(step / options.n * 100))
}
}

step = 0
write()

function write () {
if (step < options.n) {
const key = keys[step]
const frequency = frequencies[step]

stream.write(`${step++}, ${key}, ${frequency}\n`, write)
} else {
stream.end()
}
}
}
76 changes: 76 additions & 0 deletions benchmarks/self-distribution.plot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use strict'

const e = require('../lib/escape-gnuplot-string')

module.exports = function (title, description, results) {
const minHeight = 800
const height = minHeight + results.length * 300
const subtitleY = 1 - (80 / height)
const mainPlotRatio = minHeight / height
const freqPlotsRatio = 1 - mainPlotRatio
const freqPlotsbHeight = freqPlotsRatio / results.length

const keys = results.map(function (res, i) {
const file = res.csvFile
const title = results.length === 1 ? '' : res.id(results, 'default')

return `'${e(file)}' using ($1):($2) title '${e(title)}' ls ${i + 1} axes x1y1`
})

const frequencies = results.map(function (res, i) {
// Sequential keys all have a frequency of 1 which gnuplot can't handle
if (/seq/.test(res.meta.options.benchmark.keys)) return

const file = res.csvFile
const title = results.length === 1 ? '' : res.id(results, 'default')

return [
`set size 1,${freqPlotsbHeight.toFixed(3)}`,
`set origin 0.0,${((results.length - i - 1) * freqPlotsbHeight).toFixed(3)}`,
`plot '${e(file)}' using 1:3 with boxes title '' ls ${i + 1} axes x1y1`
].join('\n ')
}).filter(Boolean)

return `
reset
set terminal pngcairo truecolor enhanced font "Ubuntu Mono,10" size 1920,${height} background rgb "#1b1b1b"
set datafile separator ','

set autoscale y
set ytics mirror
set tics in
set xlabel "Step" tc rgb "#999999"

set key outside tc rgb "#999999"
set border lc rgb "#999999"

# To plot more than 5 files, add more line styles
set style line 1 lt 7 ps 0.8 lc rgb "#00FFFF"
set style line 2 lt 7 ps 0.8 lc rgb "#D84797"
set style line 3 lt 7 ps 0.8 lc rgb "#23CE6B"
set style line 4 lt 7 ps 0.8 lc rgb "#F5B700"
set style line 5 lt 7 ps 0.8 lc rgb "#731DD8"

set multiplot
set lmargin at screen 0.1

set size 1,${mainPlotRatio.toFixed(3)}
set origin 0,${freqPlotsRatio.toFixed(3)}
set title '${e(title)}' tc rgb "#cccccc" offset 0,0.7 font "Ubuntu Mono,12"
set label 1 '${e(description)}' tc rgb "#999999" at screen 0.5,${subtitleY.toFixed(3)} center front
set ylabel 'Key' tc rgb "#999999"
set nologscale y
plot ${keys.join(', ')}

set title ''
set label 1 ''
set rmargin at screen 0.97
set ylabel 'Frequency' tc rgb "#999999"
set xlabel 'Key' tc rgb "#999999"
set logscale y
set xrange [0:*]
set style fill solid

${frequencies.join('\n\n ')}
unset multiplot`
}
6 changes: 4 additions & 2 deletions level-bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ if (command === 'run') {
process.exit()
}

const type = /^self-/.test(benchmark) ? 'test' : 'benchmark'
const mainProps = type === 'test' ? ['harness'] : ['context', 'platform']
const results = files.map(Result.fromFile)
const group = results[0].group(results, { include: ['context', 'platform'] })
const title = [`benchmark ${benchmark}`, group].filter(Boolean).join(' on ')
const group = results[0].group(results, { include: mainProps })
const title = [`${type} ${benchmark}`, group].filter(Boolean).join(' on ')
const desc = results[0].group(results, { exclude: ['context', 'platform', 'harness'] }) || ''
const pngFile = path.resolve('.', argv.out || `.benchmarks/${benchmark}.${Date.now()}.png`)
const plt = benchmarks[benchmark].plot(title, desc, results)
Expand Down
3 changes: 2 additions & 1 deletion lib/result.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ class Result {
return new Result(csvFile, meta)
}

id (benches) {
id (benches, fallback) {
return this.meta.name ||
this.meta.id(benches.map(b => b.meta)) ||
fallback ||
'baseline'
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"fast-deep-equal": "~2.0.1",
"fast-glob": "~2.2.7",
"human-number": "~1.0.3",
"keyspace": "^0.0.1",
"level-test": "~7.0.0",
"mkdirp": "~0.5.1",
"monotonic-timestamp": "0.0.9",
Expand Down