mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* test: strengthen relay, persistence, and benchmark checks * test: prune fixed journal wait allowance --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
118 lines
4.1 KiB
JavaScript
118 lines
4.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// Compare per-comparison localeCompare options with hoisted Intl.Collator on Source Control refresh; assert identical sorted output before timing.
|
|
import { execFileSync } from 'node:child_process'
|
|
import { build } from 'esbuild'
|
|
import { performance } from 'node:perf_hooks'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const ITERATIONS = Number(process.env.ORCA_SC_SORT_BENCH_ITERATIONS ?? '25')
|
|
const WARMUP = Number(process.env.ORCA_SC_SORT_BENCH_WARMUP ?? '5')
|
|
|
|
for (const [name, value] of [
|
|
['ORCA_SC_SORT_BENCH_ITERATIONS', ITERATIONS],
|
|
['ORCA_SC_SORT_BENCH_WARMUP', WARMUP]
|
|
]) {
|
|
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
throw new Error(`${name} must be a positive integer, received ${value}`)
|
|
}
|
|
}
|
|
|
|
function conflictRank(entry) {
|
|
if (entry.conflictStatus === 'unresolved') {
|
|
return 0
|
|
}
|
|
if (entry.conflictStatus === 'resolved_locally') {
|
|
return 1
|
|
}
|
|
return 2
|
|
}
|
|
|
|
// Per-call baseline preserves production's locale and deterministic numeric ties.
|
|
function compareBefore(a, b) {
|
|
return (
|
|
conflictRank(a) - conflictRank(b) ||
|
|
a.path.localeCompare(b.path, 'en', { numeric: true }) ||
|
|
(a.path < b.path ? -1 : a.path > b.path ? 1 : 0)
|
|
)
|
|
}
|
|
|
|
const { outputFiles } = await build({
|
|
entryPoints: [
|
|
fileURLToPath(
|
|
new URL(
|
|
'../../src/renderer/src/components/right-sidebar/source-control-status-sort.ts',
|
|
import.meta.url
|
|
)
|
|
)
|
|
],
|
|
bundle: true,
|
|
platform: 'node',
|
|
format: 'esm',
|
|
write: false
|
|
})
|
|
const { compareGitStatusEntries: compareAfter } = await import(
|
|
`data:text/javascript;base64,${Buffer.from(outputFiles[0].text).toString('base64')}`
|
|
)
|
|
|
|
// Use real byte-sorted Git paths: shuffled input inflates win over nearly sorted production arrays.
|
|
const REPO_PATHS = execFileSync('git', ['ls-files', '-z'], {
|
|
cwd: fileURLToPath(new URL('../..', import.meta.url)),
|
|
maxBuffer: 256 * 1024 * 1024
|
|
})
|
|
.toString()
|
|
.split('\0')
|
|
.filter(Boolean)
|
|
|
|
function makeEntries(count) {
|
|
const step = Math.max(1, Math.floor(REPO_PATHS.length / count))
|
|
const paths = []
|
|
for (let index = 0; index < REPO_PATHS.length && paths.length < count; index += step) {
|
|
paths.push(REPO_PATHS[index])
|
|
}
|
|
return paths.map((path, index) => ({
|
|
path,
|
|
area: 'unstaged',
|
|
status: 'modified',
|
|
...(index % 37 === 0 ? { conflictStatus: 'unresolved' } : {})
|
|
}))
|
|
}
|
|
|
|
function measure(compare, entries) {
|
|
for (let index = 0; index < WARMUP; index += 1) {
|
|
;[...entries].sort(compare)
|
|
}
|
|
const samples = []
|
|
for (let round = 0; round < 5; round += 1) {
|
|
const start = performance.now()
|
|
for (let index = 0; index < ITERATIONS; index += 1) {
|
|
;[...entries].sort(compare)
|
|
}
|
|
samples.push((performance.now() - start) / ITERATIONS)
|
|
}
|
|
samples.sort((a, b) => a - b)
|
|
return samples[2]
|
|
}
|
|
|
|
const pad = (value, width) => String(value).padStart(width)
|
|
console.log('Source Control changed-file sort, per git refresh. Lower is better.')
|
|
console.log(`iterations=${ITERATIONS} warmup=${WARMUP} (median of 5 rounds)`)
|
|
console.log(`${pad('files', 7)} ${pad('per-call', 11)} ${pad('hoisted', 11)} ${pad('speedup', 9)}`)
|
|
|
|
// Fixture sizes follow 7,324 non-merge commits: p50 3, p75 7, p90 17, p95 26, p99 63, max 1626.
|
|
for (const count of [3, 17, 26, 63, 308, 1000]) {
|
|
const entries = makeEntries(count)
|
|
const before = [...entries].sort(compareBefore).map((entry) => entry.path)
|
|
const after = [...entries].sort(compareAfter).map((entry) => entry.path)
|
|
if (before.length !== after.length || before.some((path, index) => path !== after[index])) {
|
|
throw new Error(`sort order differs at ${count} files`)
|
|
}
|
|
const beforeMs = measure(compareBefore, entries)
|
|
const afterMs = measure(compareAfter, entries)
|
|
console.log(
|
|
`${pad(count, 7)} ${pad(`${beforeMs.toFixed(3)} ms`, 11)} ${pad(`${afterMs.toFixed(3)} ms`, 11)} ${pad(`${(beforeMs / afterMs).toFixed(1)}x`, 9)}`
|
|
)
|
|
}
|
|
console.log(
|
|
'\nSizes are the real changed-file distribution over 7,324 non-merge commits on\nthis repo (p50 3, p90 17, p95 26, p99 63), so the top rows are the common case.\nThis times the sort alone; the sort is roughly 85% of the Source Control\nprojection chain, so the end-to-end memo win is smaller than these ratios.'
|
|
)
|