A lightweight performance observer using native Node.js performance APIs for debugging and benchmarking.
npm install @neabyte/perf-observerimportperffrom'@neabyte/perf-observer'// Track a function automaticallyconsttrackedFunction=perf.track(()=>{// Your code herereturn'result'})// Manual timingperf.start('my-process')// ... do work ...constduration=perf.end('my-process')// Run benchmarksconstresult=perf.benchmark(()=>{// Function to benchmark},{iterations: 1000})| Method | Description | Returns |
|---|---|---|
start(name) | Start timing a process | void |
end(name) | End timing and get duration | number (ms) |
track(fn, name?) | Wrap function with automatic timing | Function |
getStats(name?) | Get performance statistics | ProcessStats |
findSlowProcesses(threshold?) | Find processes exceeding threshold | ProcessEntry[] |
benchmark(fn, options?) | Run benchmark test | BenchmarkResult |
| Property | Type | Description |
|---|---|---|
count | number | Number of processes |
avgDuration | number | Average duration (ms) |
minDuration | number | Minimum duration (ms) |
maxDuration | number | Maximum duration (ms) |
p95Duration | number | 95th percentile (ms) |
p99Duration | number | 99th percentile (ms) |
| Property | Type | Default | Description |
|---|---|---|---|
iterations | number | 1000 | Number of test iterations |
warmup | number | min(100, iterations/10) | Warmup iterations |
maxDuration | number | 60000 | Max test duration (ms) |
outlierThreshold | number | 3 | Outlier detection threshold |
trackMemory | boolean | false | Track memory usage |
name | string | fn.name | Custom benchmark name |
| Property | Type | Description |
|---|---|---|
name | string | Benchmark name |
iterations | number | Actual iterations completed |
warmupIterations | number | Warmup iterations performed |
totalTime | number | Total time (ms) |
avgTime | number | Average time per iteration (ms) |
minTime | number | Minimum iteration time (ms) |
maxTime | number | Maximum iteration time (ms) |
p95Time | number | 95th percentile time (ms) |
p99Time | number | 99th percentile time (ms) |
stdDev | number | Standard deviation |
outliers | number | Number of outliers removed |
memoryDelta | number? | Memory usage change (bytes) |
// Manual timingperf.start('database-query')// Simulate database operationawaitnewPromise(resolve=>setTimeout(resolve,50))constduration=perf.end('database-query')console.log(`Query took ${duration}ms`)// Automatic timingconstexpensiveOperation=perf.track(async()=>{awaitnewPromise(resolve=>setTimeout(resolve,100))return'completed'})constresult=awaitexpensiveOperation()Duplicate Name Behavior: Multiple functions with the same name will overwrite each other's performance data. Only the last function's data will be preserved in statistics. To avoid data loss:
- Use unique names:
perf.track(fn, 'unique-name')- Add hash suffixes:
perf.track(fn, 'operation-' + crypto.randomBytes(4).toString('hex'))- Use function names:
function myOperation() {}thenperf.track(myOperation)Anonymous functions all use 'anonymous' name and will overwrite each other.
// Get stats for all processesconstallStats=perf.getStats()console.log(`Average: ${allStats.avgDuration}ms`)// Get stats for specific processconstqueryStats=perf.getStats('database-query')console.log(`95th percentile: ${queryStats.p95Duration}ms`)// Simple benchmarkconstresult=perf.benchmark(()=>{returnMath.random()*1000},10000)console.log(`Average: ${result.avgTime}ms`)console.log(`Standard deviation: ${result.stdDev}ms`)// Advanced benchmark with optionsconstadvancedResult=perf.benchmark(()=>{// Simulate data processingreturnArray.from({length: 1000},(_,i)=>i*2)},{iterations: 5000,warmup: 100,trackMemory: true,outlierThreshold: 2,name: 'data-processing'})// Find processes taking longer than 1 secondconstslowProcesses=perf.findSlowProcesses(1000)slowProcesses.forEach(process=>{console.log(`${process.name}: ${process.duration}ms`)})- Node.js >= 22.0.0
- TypeScript (optional, for type definitions)
Issues and pull requests are welcome on GitHub.
This project is licensed under the MIT license. See the LICENSE file for more info.