import { launch } from 'puppeteer'
import colors from 'picocolors'
import { exec, getSha } from '../scripts/utils.js'
+import process from 'node:process'
+import readline from 'node:readline'
// Thanks to https://github.com/krausest/js-framework-benchmark (Apache-2.0 license)
const {
noVapor,
port: portStr,
count: countStr,
+ warmupCount: warmupCountStr,
noHeadless,
devBuild,
},
short: 'c',
default: '30',
},
+ warmupCount: {
+ type: 'string',
+ short: 'w',
+ default: '5',
+ },
noHeadless: {
type: 'boolean',
},
const port = +(/** @type {string}*/ (portStr))
const count = +(/** @type {string}*/ (countStr))
+const warmupCount = +(/** @type {string}*/ (warmupCountStr))
const sha = await getSha(true)
if (!skipLib) {
await forceGC()
const t = performance.now()
- for (let i = 0; i < count; i++) {
- await clickButton('run') // test: create rows
- await clickButton('update') // partial update
- await clickButton('swaprows') // swap rows
- await select() // test: select row, remove row
- await clickButton('clear') // clear rows
+ console.log('warmup run')
+ await eachRun(() => withoutRecord(benchOnce), warmupCount)
- await withoutRecord(() => clickButton('run'))
- await clickButton('add') // append rows to large table
-
- await withoutRecord(() => clickButton('clear'))
- await clickButton('runLots') // create many rows
- await withoutRecord(() => clickButton('clear'))
-
- // TODO replace all rows
- }
+ console.log('benchmark run')
+ await eachRun(benchOnce, count)
console.info(
'Total time:',
await page.close()
return result
+ async function benchOnce() {
+ await clickButton('run') // test: create rows
+ await clickButton('update') // partial update
+ await clickButton('swaprows') // swap rows
+ await select() // test: select row, remove row
+ await clickButton('clear') // clear rows
+
+ await withoutRecord(() => clickButton('run'))
+ await clickButton('add') // append rows to large table
+
+ await withoutRecord(() => clickButton('clear'))
+ await clickButton('runLots') // create many rows
+ await withoutRecord(() => clickButton('clear'))
+
+ // TODO replace all rows
+ }
+
function getTimes() {
return page.evaluate(() => /** @type {any} */ (globalThis).times)
}
/** @param {() => any} fn */
async function withoutRecord(fn) {
+ const currentRecordTime = await page.evaluate(() => globalThis.recordTime)
await page.evaluate(() => (globalThis.recordTime = false))
await fn()
- await page.evaluate(() => (globalThis.recordTime = true))
+ await page.evaluate(
+ currentRecordTime => (globalThis.recordTime = currentRecordTime),
+ currentRecordTime,
+ )
}
/** @param {string} id */
}
}
+/**
+ * @param {Function} bench
+ * @param {number} count
+ */
+async function eachRun(bench, count) {
+ for (let i = 0; i < count; i++) {
+ readline.cursorTo(process.stdout, 0)
+ readline.clearLine(process.stdout, 0)
+ process.stdout.write(`${i + 1}/${count}`)
+ await bench()
+ }
+ if (count === 0) {
+ process.stdout.write('0/0 (skip)')
+ }
+ process.stdout.write('\n')
+}
+
async function initBrowser() {
const disableFeatures = [
'Translate', // avoid translation popups