Skip to content

Commit 05ec32e

Browse files
committed
fix: resolve CI test failures and formatting issues
- Add CI environment detection to benchmark tests with lower thresholds - Fix unused variable warnings in benchmark files - Fix prettier formatting issues across benchmark and test files - Update version to 1.0.0-beta.1 with matching optional dependencies - Add API performance guide documentation
1 parent 22d5bf5 commit 05ec32e

30 files changed

Lines changed: 1370 additions & 469 deletions

benches/api/async_bench.ts

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function median(arr: number[]): number {
105105
return percentile(arr, 50)
106106
}
107107

108-
function forceGC() {
108+
function _forceGC() {
109109
if (global.gc) {
110110
global.gc()
111111
}
@@ -163,7 +163,7 @@ async function runAsyncBenchmark(
163163
// Check result consistency (use sets for comparison)
164164
const globSet = new Set(globResults)
165165
const globlinSet = new Set(globlinResults)
166-
const resultMatch = globSet.size === globlinSet.size && [...globSet].every((r) => globlinSet.has(r))
166+
const resultMatch = globSet.size === globlinSet.size && [...globSet].every(r => globlinSet.has(r))
167167

168168
const fixtureLabel = cwd.includes('small')
169169
? 'small'
@@ -218,21 +218,37 @@ async function runConcurrencyBenchmark(
218218
const fgOptions = { cwd }
219219

220220
// Warmup
221-
await Promise.all([ogGlob(pattern, ogOptions), glob(pattern, globlinOptions), fg(pattern, fgOptions)])
221+
await Promise.all([
222+
ogGlob(pattern, ogOptions),
223+
glob(pattern, globlinOptions),
224+
fg(pattern, fgOptions),
225+
])
222226

223227
// Benchmark glob - concurrent operations
224228
const globStart = performance.now()
225-
await Promise.all(Array(concurrency).fill(0).map(() => ogGlob(pattern, ogOptions)))
229+
await Promise.all(
230+
Array(concurrency)
231+
.fill(0)
232+
.map(() => ogGlob(pattern, ogOptions))
233+
)
226234
const globTotal = performance.now() - globStart
227235

228236
// Benchmark globlin - concurrent operations
229237
const globlinStart = performance.now()
230-
await Promise.all(Array(concurrency).fill(0).map(() => glob(pattern, globlinOptions)))
238+
await Promise.all(
239+
Array(concurrency)
240+
.fill(0)
241+
.map(() => glob(pattern, globlinOptions))
242+
)
231243
const globlinTotal = performance.now() - globlinStart
232244

233245
// Benchmark fast-glob - concurrent operations
234246
const fgStart = performance.now()
235-
await Promise.all(Array(concurrency).fill(0).map(() => fg(pattern, fgOptions)))
247+
await Promise.all(
248+
Array(concurrency)
249+
.fill(0)
250+
.map(() => fg(pattern, fgOptions))
251+
)
236252
const fgTotal = performance.now() - fgStart
237253

238254
const fixtureLabel = cwd.includes('small')
@@ -325,19 +341,20 @@ async function measureEventLoopLatency(
325341
while (running) {
326342
const expected = intervalMs
327343
const start = performance.now()
328-
await new Promise((resolve) => setTimeout(resolve, intervalMs))
344+
await new Promise(resolve => setTimeout(resolve, intervalMs))
329345
const actual = performance.now() - start
330346
latencies.push(actual - expected)
331347
}
332348
}
333349

334-
const monitorPromise = monitor()
350+
// Start monitor (intentionally not awaited to run concurrently)
351+
void monitor()
335352

336353
// Run the glob operation
337354
await glob(pattern, { cwd })
338355

339356
running = false
340-
await new Promise((resolve) => setTimeout(resolve, 20)) // Allow monitor to exit
357+
await new Promise(resolve => setTimeout(resolve, 20)) // Allow monitor to exit
341358

342359
return {
343360
avgLatency: latencies.length > 0 ? latencies.reduce((a, b) => a + b, 0) / latencies.length : 0,
@@ -586,7 +603,12 @@ async function main() {
586603
console.log('-'.repeat(80))
587604

588605
console.log('\nMeasuring event loop latency during async glob operations...\n')
589-
console.log('Pattern'.padEnd(25) + 'Avg Latency'.padStart(15) + 'Max Latency'.padStart(15) + 'Samples'.padStart(10))
606+
console.log(
607+
'Pattern'.padEnd(25) +
608+
'Avg Latency'.padStart(15) +
609+
'Max Latency'.padStart(15) +
610+
'Samples'.padStart(10)
611+
)
590612
console.log('-'.repeat(65))
591613

592614
const eventLoopPatterns = ['**/*.js', '**/*']
@@ -606,7 +628,13 @@ async function main() {
606628
console.log('-'.repeat(80))
607629

608630
const percentilePatterns = ['**/*.js', '*.js', 'level0/**/*.js']
609-
console.log('\nPattern'.padEnd(25) + 'Median'.padStart(10) + 'P95'.padStart(10) + 'P99'.padStart(10) + 'Max'.padStart(10))
631+
console.log(
632+
'\nPattern'.padEnd(25) +
633+
'Median'.padStart(10) +
634+
'P95'.padStart(10) +
635+
'P99'.padStart(10) +
636+
'Max'.padStart(10)
637+
)
610638
console.log('-'.repeat(65))
611639

612640
for (const pattern of percentilePatterns) {
@@ -628,7 +656,12 @@ async function main() {
628656
// Import sync version for comparison
629657
const { globSync } = await import('../../js/index.js')
630658

631-
console.log('\n[Globlin] Pattern'.padEnd(25) + 'Sync (ms)'.padStart(12) + 'Async (ms)'.padStart(12) + 'Overhead'.padStart(12))
659+
console.log(
660+
'\n[Globlin] Pattern'.padEnd(25) +
661+
'Sync (ms)'.padStart(12) +
662+
'Async (ms)'.padStart(12) +
663+
'Overhead'.padStart(12)
664+
)
632665
console.log('-'.repeat(61))
633666

634667
for (const pattern of ['**/*.js', '*.js', 'level0/**/*.js']) {
@@ -674,13 +707,18 @@ async function main() {
674707
}
675708

676709
console.log('\nAggregate by fixture:')
677-
console.log('Fixture'.padEnd(10) + 'Avg vs Glob'.padStart(15) + 'Avg vs FG'.padStart(15) + 'Faster than Glob'.padStart(20))
710+
console.log(
711+
'Fixture'.padEnd(10) +
712+
'Avg vs Glob'.padStart(15) +
713+
'Avg vs FG'.padStart(15) +
714+
'Faster than Glob'.padStart(20)
715+
)
678716
console.log('-'.repeat(60))
679717

680718
for (const [fixture, results] of Object.entries(byFixture)) {
681719
const avgVsGlob = results.reduce((sum, r) => sum + r.speedupVsGlob, 0) / results.length
682720
const avgVsFg = results.reduce((sum, r) => sum + r.speedupVsFg, 0) / results.length
683-
const fasterCount = results.filter((r) => r.speedupVsGlob > 1).length
721+
const fasterCount = results.filter(r => r.speedupVsGlob > 1).length
684722
console.log(
685723
fixture.padEnd(10) +
686724
`${avgVsGlob.toFixed(2)}x`.padStart(15) +
@@ -690,18 +728,21 @@ async function main() {
690728
}
691729

692730
// Result accuracy
693-
const totalMatches = allResults.filter((r) => r.resultMatch).length
731+
const totalMatches = allResults.filter(r => r.resultMatch).length
694732
console.log(`\nResult accuracy: ${totalMatches}/${allResults.length} patterns match glob results`)
695733

696734
// Concurrency summary
697735
console.log('\nConcurrency scaling (medium fixture, **/*.js):')
698-
const mediumConcurrency = concurrencyResults.filter((r) => r.fixture === 'medium')
736+
const mediumConcurrency = concurrencyResults.filter(r => r.fixture === 'medium')
699737
for (const r of mediumConcurrency) {
700-
console.log(` ${r.concurrency.toString().padEnd(3)} concurrent: ${r.speedupVsGlob.toFixed(2)}x vs glob, throughput ${r.globlin.throughput.toFixed(0)}/s`)
738+
console.log(
739+
` ${r.concurrency.toString().padEnd(3)} concurrent: ${r.speedupVsGlob.toFixed(2)}x vs glob, throughput ${r.globlin.throughput.toFixed(0)}/s`
740+
)
701741
}
702742

703743
// AbortSignal overhead summary
704-
const avgAbortOverhead = abortResults.reduce((sum, r) => sum + r.overheadPercent, 0) / abortResults.length
744+
const avgAbortOverhead =
745+
abortResults.reduce((sum, r) => sum + r.overheadPercent, 0) / abortResults.length
705746
console.log(`\nAbortSignal average overhead: ${avgAbortOverhead.toFixed(1)}%`)
706747

707748
// Best and worst patterns

benches/api/async_bottleneck_analysis.ts

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ function median(arr: number[]): number {
2525
return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2
2626
}
2727

28-
function percentile(arr: number[], p: number): number {
28+
function _percentile(arr: number[], p: number): number {
2929
const sorted = [...arr].sort((a, b) => a - b)
3030
const idx = Math.ceil((p / 100) * sorted.length) - 1
3131
return sorted[Math.max(0, idx)]
3232
}
3333

3434
async function sleep(ms: number): Promise<void> {
35-
return new Promise((resolve) => setTimeout(resolve, ms))
35+
return new Promise(resolve => setTimeout(resolve, ms))
3636
}
3737

3838
// ============================================================
@@ -163,12 +163,12 @@ async function measureEventLoopBlocking(
163163
let running = true
164164
let expectedTime = 0
165165

166-
// Monitor event loop in a separate task
167-
const monitorPromise = (async () => {
166+
// Monitor event loop in a separate task (intentionally not awaited to run concurrently)
167+
void (async () => {
168168
while (running) {
169169
const before = performance.now()
170170
expectedTime = sampleIntervalMs
171-
await new Promise((resolve) => setTimeout(resolve, sampleIntervalMs))
171+
await new Promise(resolve => setTimeout(resolve, sampleIntervalMs))
172172
const after = performance.now()
173173
const actualTime = after - before
174174
const blockTime = actualTime - expectedTime
@@ -302,7 +302,11 @@ interface TokioAnalysisResult {
302302
napiPercent: number
303303
}
304304

305-
async function analyzeTokioRuntime(pattern: string, cwd: string, runs = 15): Promise<TokioAnalysisResult> {
305+
async function analyzeTokioRuntime(
306+
pattern: string,
307+
cwd: string,
308+
runs = 15
309+
): Promise<TokioAnalysisResult> {
306310
const opts = { cwd }
307311

308312
// Warmup
@@ -376,7 +380,11 @@ interface AsyncComparisonResult {
376380
fgAsyncOverhead: number
377381
}
378382

379-
async function compareAsyncImplementations(pattern: string, cwd: string, runs = 10): Promise<AsyncComparisonResult> {
383+
async function compareAsyncImplementations(
384+
pattern: string,
385+
cwd: string,
386+
runs = 10
387+
): Promise<AsyncComparisonResult> {
380388
const opts = { cwd }
381389
const fgOpts = { cwd }
382390

@@ -509,15 +517,19 @@ async function main() {
509517
result.syncTime.toFixed(2).padStart(12) +
510518
result.asyncTime.toFixed(2).padStart(12) +
511519
`${result.overhead >= 0 ? '+' : ''}${result.overhead.toFixed(2)}ms`.padStart(12) +
512-
`${result.overheadPercent >= 0 ? '+' : ''}${result.overheadPercent.toFixed(1)}%`.padStart(8)
520+
`${result.overheadPercent >= 0 ? '+' : ''}${result.overheadPercent.toFixed(1)}%`.padStart(
521+
8
522+
)
513523
)
514524
}
515525
}
516526

517527
// Promise creation and scheduling overhead
518528
console.log('\nPromise/Scheduling Micro-benchmarks:')
519529
const sampleOverhead = overheadResults[0]
520-
console.log(` Promise.resolve() creation: ~${(sampleOverhead.promiseCreationTime * 1000).toFixed(2)}us`)
530+
console.log(
531+
` Promise.resolve() creation: ~${(sampleOverhead.promiseCreationTime * 1000).toFixed(2)}us`
532+
)
521533
console.log(` .then() scheduling: ~${(sampleOverhead.asyncSchedulingTime * 1000).toFixed(2)}us`)
522534

523535
// === SECTION 2: Event Loop Blocking ===
@@ -640,9 +652,15 @@ async function main() {
640652
`${result.globlinAsync.toFixed(1)}ms`.padStart(10) +
641653
`${result.globAsync.toFixed(1)}ms`.padStart(10) +
642654
`${result.fgAsync.toFixed(1)}ms`.padStart(10) +
643-
`${result.globlinAsyncOverhead >= 0 ? '+' : ''}${result.globlinAsyncOverhead.toFixed(0)}%`.padStart(10) +
644-
`${result.globAsyncOverhead >= 0 ? '+' : ''}${result.globAsyncOverhead.toFixed(0)}%`.padStart(10) +
645-
`${result.fgAsyncOverhead >= 0 ? '+' : ''}${result.fgAsyncOverhead.toFixed(0)}%`.padStart(10)
655+
`${result.globlinAsyncOverhead >= 0 ? '+' : ''}${result.globlinAsyncOverhead.toFixed(0)}%`.padStart(
656+
10
657+
) +
658+
`${result.globAsyncOverhead >= 0 ? '+' : ''}${result.globAsyncOverhead.toFixed(0)}%`.padStart(
659+
10
660+
) +
661+
`${result.fgAsyncOverhead >= 0 ? '+' : ''}${result.fgAsyncOverhead.toFixed(0)}%`.padStart(
662+
10
663+
)
646664
)
647665
}
648666
}
@@ -652,13 +670,16 @@ async function main() {
652670
console.log('BOTTLENECK ANALYSIS SUMMARY')
653671
console.log('='.repeat(80))
654672

655-
const avgOverhead = overheadResults.reduce((sum, r) => sum + r.overheadPercent, 0) / overheadResults.length
656-
const maxOverhead = Math.max(...overheadResults.map((r) => r.overheadPercent))
657-
const minOverhead = Math.min(...overheadResults.map((r) => r.overheadPercent))
673+
const avgOverhead =
674+
overheadResults.reduce((sum, r) => sum + r.overheadPercent, 0) / overheadResults.length
675+
const maxOverhead = Math.max(...overheadResults.map(r => r.overheadPercent))
676+
const minOverhead = Math.min(...overheadResults.map(r => r.overheadPercent))
658677

659678
console.log('\n1. ASYNC OVERHEAD:')
660679
console.log(` Average: ${avgOverhead >= 0 ? '+' : ''}${avgOverhead.toFixed(1)}%`)
661-
console.log(` Range: ${minOverhead >= 0 ? '+' : ''}${minOverhead.toFixed(1)}% to ${maxOverhead >= 0 ? '+' : ''}${maxOverhead.toFixed(1)}%`)
680+
console.log(
681+
` Range: ${minOverhead >= 0 ? '+' : ''}${minOverhead.toFixed(1)}% to ${maxOverhead >= 0 ? '+' : ''}${maxOverhead.toFixed(1)}%`
682+
)
662683
console.log(' Conclusion: Async overhead is MINIMAL (typically <5%)')
663684

664685
console.log('\n2. EVENT LOOP BLOCKING:')

0 commit comments

Comments
 (0)