chore: crush git history - reborn from consolidation on 2026-03-10
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { performance } from 'node:perf_hooks'
|
||||
|
||||
function percentile(sorted, p) {
|
||||
if (sorted.length === 0) return 0
|
||||
const idx = Math.min(sorted.length - 1, Math.floor(sorted.length * p))
|
||||
return sorted[idx]
|
||||
}
|
||||
|
||||
export function getBenchOptions() {
|
||||
const runs = Number.parseInt(process.env.BENCH_RUNS ?? '8', 10)
|
||||
const warmup = Number.parseInt(process.env.BENCH_WARMUP ?? '2', 10)
|
||||
return {
|
||||
runs: Number.isFinite(runs) && runs > 1 ? runs : 8,
|
||||
warmup: Number.isFinite(warmup) && warmup >= 0 ? warmup : 2,
|
||||
}
|
||||
}
|
||||
|
||||
export async function measure(name, fn, options) {
|
||||
const times = []
|
||||
|
||||
for (let i = 0; i < options.runs; i++) {
|
||||
const t0 = performance.now()
|
||||
await fn()
|
||||
const dt = performance.now() - t0
|
||||
if (i >= options.warmup) {
|
||||
times.push(dt)
|
||||
}
|
||||
}
|
||||
|
||||
times.sort((a, b) => a - b)
|
||||
const mean = times.reduce((sum, value) => sum + value, 0) / Math.max(1, times.length)
|
||||
|
||||
return {
|
||||
name,
|
||||
samples: times.length,
|
||||
mean,
|
||||
min: times[0] ?? 0,
|
||||
p50: percentile(times, 0.5),
|
||||
p95: percentile(times, 0.95),
|
||||
max: times[times.length - 1] ?? 0,
|
||||
}
|
||||
}
|
||||
|
||||
export function printResults(title, results, options) {
|
||||
console.log(`\n${title}`)
|
||||
console.log(`runs=${options.runs} warmup=${options.warmup} measured=${Math.max(0, options.runs - options.warmup)}`)
|
||||
for (const row of results) {
|
||||
console.log(
|
||||
`${row.name.padEnd(32)} n=${String(row.samples).padStart(2)} mean=${row.mean.toFixed(1)}ms ` +
|
||||
`p50=${row.p50.toFixed(1)}ms p95=${row.p95.toFixed(1)}ms min=${row.min.toFixed(1)}ms max=${row.max.toFixed(1)}ms`
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { getBenchOptions, measure, printResults } from './_shared.mjs'
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
const repoRoot = resolve(__dirname, '..', '..')
|
||||
|
||||
const options = getBenchOptions()
|
||||
const generationProfiles = (process.env.BENCH_GENERATION_PROFILES ?? 'default,quick,standard,thorough')
|
||||
.split(',')
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean)
|
||||
|
||||
function withGenerationProfile(baseArgs, profile) {
|
||||
if (profile === 'default') {
|
||||
return baseArgs
|
||||
}
|
||||
return [...baseArgs, '--generation-profile', profile]
|
||||
}
|
||||
|
||||
const scenarios = [
|
||||
{ name: 'cli.help', args: ['--help'] },
|
||||
{ name: 'cli.version', args: ['--version'] },
|
||||
{ name: 'cli.doctor', args: ['doctor', '--cwd', 'src/cli/__fixtures__/tiny-fastify', '--quiet'] },
|
||||
{ name: 'cli.observe.check', args: ['observe', '--cwd', 'src/cli/__fixtures__/observe-config', '--profile', 'staging-observe', '--check-config', '--quiet'] },
|
||||
...generationProfiles.map((profile) => ({
|
||||
name: `cli.qualify.profile[${profile}]`,
|
||||
args: withGenerationProfile(
|
||||
['qualify', '--cwd', 'src/cli/__fixtures__/protocol-lab', '--profile', 'oauth-nightly', '--seed', '42', '--quiet'],
|
||||
profile,
|
||||
),
|
||||
})),
|
||||
]
|
||||
|
||||
async function run() {
|
||||
const results = []
|
||||
|
||||
for (const scenario of scenarios) {
|
||||
const row = await measure(
|
||||
scenario.name,
|
||||
async () => {
|
||||
const proc = spawnSync(
|
||||
process.execPath,
|
||||
['dist/cli/index.js', ...scenario.args],
|
||||
{
|
||||
cwd: repoRoot,
|
||||
stdio: 'pipe',
|
||||
encoding: 'utf8',
|
||||
env: { ...process.env, FORCE_COLOR: '0' },
|
||||
}
|
||||
)
|
||||
|
||||
if (proc.status !== 0) {
|
||||
throw new Error(
|
||||
`Scenario ${scenario.name} failed with code ${proc.status}\nstdout:\n${proc.stdout}\nstderr:\n${proc.stderr}`
|
||||
)
|
||||
}
|
||||
},
|
||||
options,
|
||||
)
|
||||
|
||||
results.push(row)
|
||||
}
|
||||
|
||||
printResults('CLI Benchmarks', results, options)
|
||||
}
|
||||
|
||||
run().catch((error) => {
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -0,0 +1,163 @@
|
||||
import { resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import * as fc from 'fast-check'
|
||||
|
||||
import { parse, clearParseCache } from '../../dist/formula/parser.js'
|
||||
import { evaluate } from '../../dist/formula/evaluator.js'
|
||||
import { matchRoutePattern, findMatchingRoute } from '../../dist/infrastructure/route-matcher.js'
|
||||
import { convertSchema } from '../../dist/domain/schema-to-arbitrary.js'
|
||||
import { qualifyCommand } from '../../dist/cli/commands/qualify/index.js'
|
||||
import { createContext } from '../../dist/cli/core/context.js'
|
||||
import { getBenchOptions, measure, printResults } from './_shared.mjs'
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
const repoRoot = resolve(__dirname, '..', '..')
|
||||
|
||||
process.chdir(repoRoot)
|
||||
|
||||
const options = getBenchOptions()
|
||||
const MICRO_ITERS = Number.parseInt(process.env.BENCH_INNER_ITERS ?? '2000', 10)
|
||||
const generationProfiles = (process.env.BENCH_GENERATION_PROFILES ?? 'quick,standard,thorough')
|
||||
.split(',')
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean)
|
||||
|
||||
const formula = 'response_code(this) == 200 && response_body(this).id != null && response_time(this) < 500'
|
||||
const formulaPool = [
|
||||
formula,
|
||||
'response_payload(this).user.id != null && response_code(this) == 200',
|
||||
'request_headers(this).authorization != null => response_code(this) != 401',
|
||||
"response_body(this).name matches '^[A-Za-z ]+$'",
|
||||
]
|
||||
|
||||
const parsedFormula = parse(formula).ast
|
||||
const evalCtx = {
|
||||
request: {
|
||||
body: { name: 'Alice' },
|
||||
headers: { authorization: 'Bearer token' },
|
||||
query: {},
|
||||
params: {},
|
||||
cookies: {},
|
||||
},
|
||||
response: {
|
||||
body: { id: 'usr-1', name: 'Alice' },
|
||||
headers: {},
|
||||
statusCode: 200,
|
||||
responseTime: 42,
|
||||
},
|
||||
}
|
||||
|
||||
const routePatterns = Array.from({ length: 50 }, (_, i) => `/v1/resources/${i}/:id`)
|
||||
routePatterns.push('/v1/resources/target/:id')
|
||||
|
||||
const complexSchema = {
|
||||
type: 'object',
|
||||
required: ['id', 'email', 'profile'],
|
||||
properties: {
|
||||
id: { type: 'string', minLength: 1, maxLength: 64 },
|
||||
email: { type: 'string', format: 'email' },
|
||||
tags: { type: 'array', items: { type: 'string', minLength: 1 }, minItems: 0, maxItems: 10 },
|
||||
profile: {
|
||||
type: 'object',
|
||||
required: ['age', 'active'],
|
||||
properties: {
|
||||
age: { type: 'integer', minimum: 18, maximum: 90 },
|
||||
active: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
}
|
||||
|
||||
const qualifyCtx = createContext({
|
||||
cwd: repoRoot,
|
||||
quiet: true,
|
||||
format: 'human',
|
||||
color: 'never',
|
||||
})
|
||||
|
||||
async function run() {
|
||||
const results = []
|
||||
|
||||
results.push(await measure('formula.parse.cache-hit', async () => {
|
||||
for (let i = 0; i < MICRO_ITERS; i++) {
|
||||
parse(formula)
|
||||
}
|
||||
}, options))
|
||||
|
||||
results.push(await measure('formula.parse.cache-miss', async () => {
|
||||
for (let i = 0; i < Math.max(1, Math.floor(MICRO_ITERS / 20)); i++) {
|
||||
clearParseCache()
|
||||
for (const candidate of formulaPool) {
|
||||
parse(candidate)
|
||||
}
|
||||
}
|
||||
}, options))
|
||||
|
||||
results.push(await measure('formula.evaluate', async () => {
|
||||
for (let i = 0; i < MICRO_ITERS; i++) {
|
||||
const result = evaluate(parsedFormula, evalCtx)
|
||||
if (!result.success) {
|
||||
throw new Error(result.error)
|
||||
}
|
||||
}
|
||||
}, options))
|
||||
|
||||
results.push(await measure('route.match.single', async () => {
|
||||
let matched = true
|
||||
for (let i = 0; i < MICRO_ITERS; i++) {
|
||||
matched = matchRoutePattern('/v1/resources/target/:id', '/v1/resources/target/abc-123').matched
|
||||
}
|
||||
if (!matched) {
|
||||
throw new Error('Expected route pattern to match')
|
||||
}
|
||||
}, options))
|
||||
|
||||
results.push(await measure('route.match.collection', async () => {
|
||||
let match = null
|
||||
for (let i = 0; i < MICRO_ITERS; i++) {
|
||||
match = findMatchingRoute(routePatterns, '/v1/resources/target/abc-123')
|
||||
}
|
||||
if (!match) {
|
||||
throw new Error('Expected to find matching route')
|
||||
}
|
||||
}, options))
|
||||
|
||||
for (const generationProfile of generationProfiles) {
|
||||
const schemaArbitrary = convertSchema(complexSchema, { context: 'request', generationProfile })
|
||||
|
||||
results.push(await measure(`schema.convert[${generationProfile}]`, async () => {
|
||||
for (let i = 0; i < Math.max(1, Math.floor(MICRO_ITERS / 10)); i++) {
|
||||
convertSchema(complexSchema, { context: 'request', generationProfile })
|
||||
}
|
||||
}, options))
|
||||
|
||||
results.push(await measure(`schema.sample[${generationProfile}]`, async () => {
|
||||
for (let i = 0; i < Math.max(1, Math.floor(MICRO_ITERS / 10)); i++) {
|
||||
fc.sample(schemaArbitrary, 1)
|
||||
}
|
||||
}, options))
|
||||
|
||||
const qualifyOptions = {
|
||||
cwd: 'src/cli/__fixtures__/protocol-lab',
|
||||
profile: 'oauth-nightly',
|
||||
generationProfile,
|
||||
seed: 42,
|
||||
format: 'human',
|
||||
}
|
||||
results.push(await measure(`qualify.command.in-process[${generationProfile}]`, async () => {
|
||||
const result = await qualifyCommand(qualifyOptions, qualifyCtx)
|
||||
if (result.exitCode !== 0) {
|
||||
throw new Error(`qualifyCommand failed with ${result.exitCode}: ${result.message ?? ''}`)
|
||||
}
|
||||
}, options))
|
||||
}
|
||||
|
||||
printResults('Hot Path Benchmarks', results, options)
|
||||
}
|
||||
|
||||
run().catch((error) => {
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user