|
| 1 | +import { styleText } from 'node:util' |
1 | 2 | import Hold from './index.js'
|
2 | 3 | import crypto from 'node:crypto'
|
3 | 4 |
|
4 |
| -export default function benchTurbo (holder) { |
5 |
| - holder ||= Hold({ turbo: true }) |
| 5 | +export default function benchTurbo (holder, { |
| 6 | + targetTime = 500, |
| 7 | + threshold = 1000, |
| 8 | + maxRuns = 10, |
| 9 | + growth = 1.01, |
| 10 | + retraction = 0.99, |
| 11 | + lower = 1, |
| 12 | + upper = 1000000 |
| 13 | +} = {}) { |
6 | 14 | const records = []
|
| 15 | + let runCount = 0 |
| 16 | + |
| 17 | + function log ({ a, b, c, time, col = null }) { |
| 18 | + const pad = (str) => `${str}`.padStart(('' + upper).length, ' ') |
| 19 | + const aStr = col === 'a' ? styleText('green', pad(a)) : pad(a) |
| 20 | + const bStr = col === 'b' ? styleText('green', pad(b)) : pad(b) |
| 21 | + const cStr = col === 'c' ? styleText('green', pad(c)) : pad(c) |
| 22 | + const timeStr = time < targetTime ? time.toFixed(3) : styleText('red', time.toFixed(3)) |
| 23 | + |
| 24 | + console.log(`Run: ${('' + runCount).padStart(('' + maxRuns).length, ' ')} |`, aStr, cStr, bStr, '|', timeStr + 'ms') |
| 25 | + } |
| 26 | + |
| 27 | + function record ({ a, c, b, time, col }) { |
| 28 | + log(...arguments) |
7 | 29 |
|
8 |
| - function record (rec, time) { |
9 | 30 | records.push({
|
10 |
| - 'Time (ms)': time, |
11 |
| - 'Record Count': rec, |
12 |
| - 'Recods per ms': Number((rec / time).toFixed(3)) |
| 31 | + Run: runCount, |
| 32 | + 'Time (ms)': Number(time.toFixed(3)), |
| 33 | + 'Record Count': arguments[0][col], |
| 34 | + 'Recods per ms': Number((arguments[0][col] / time).toFixed(3)) |
13 | 35 | })
|
14 | 36 | }
|
15 | 37 |
|
16 | 38 | function run (count) {
|
| 39 | + const db = Hold({ turbo: true }) |
| 40 | + |
17 | 41 | const tableName = crypto.createHash('sha1').update(('b' + new Date().valueOf() + count)).digest('hex')
|
18 |
| - holder.init(tableName, 'keyX', 'valueX') |
| 42 | + db.init(tableName, 'keyX', 'valueX') |
19 | 43 |
|
20 |
| - const entries = Array.from(Array(count)).map((_, i) => holder.prepare(tableName, `key${i}`, `value${i}`)) |
| 44 | + const entries = Array.from(Array(count)).map((_, i) => db.prepare(tableName, `key${i}`, `value${i}`)) |
21 | 45 |
|
22 | 46 | const start = performance.now()
|
23 |
| - holder.setBulk(tableName, 'keyX', entries) |
| 47 | + db.setBulk(tableName, 'keyX', entries) |
24 | 48 |
|
25 | 49 | return performance.now() - start
|
26 | 50 | }
|
27 | 51 |
|
28 | 52 | function bisect (a, b) {
|
29 |
| - if ((b - a) <= 1000) return Math.round((a + b) / 2) |
| 53 | + runCount++ |
| 54 | + if ((b - a) <= threshold || runCount > maxRuns) return Math.round((a + b) / 2) |
30 | 55 |
|
31 | 56 | const c = Math.round((a + b) / 2)
|
32 |
| - |
33 | 57 | const cTime = run(c)
|
34 |
| - if (cTime < 1000) { |
35 |
| - record(c, cTime) |
36 |
| - return bisect(c, Math.round(b * 1.02), 'c') |
| 58 | + |
| 59 | + if (cTime < targetTime) { |
| 60 | + record({ a, c, b, time: cTime, col: 'c' }) |
| 61 | + return bisect(c, Math.round(b * growth), 'c') |
37 | 62 | }
|
38 | 63 |
|
39 | 64 | const aTime = run(a)
|
40 |
| - if (aTime < 1000) { |
41 |
| - record(a, aTime) |
| 65 | + if (aTime < targetTime) { |
| 66 | + record({ a, b, c, time: aTime, col: 'a' }) |
42 | 67 | return bisect(a, c, 'a')
|
43 | 68 | }
|
44 | 69 |
|
45 |
| - return bisect(Math.round(a * 0.98), c, null) |
| 70 | + log({ a, c, b, time: cTime }) |
| 71 | + return bisect(Math.round(a * retraction), c, null) |
46 | 72 | }
|
47 | 73 |
|
48 |
| - bisect(1, 150000, null) |
| 74 | + bisect(lower, upper, null) |
49 | 75 |
|
50 | 76 | return records.sort((a, b) => b['Recods per ms'] - a['Recods per ms']).slice(0, 3)
|
51 | 77 | }
|
0 commit comments