Files
go-jdenticon/benchmark/benchmark-js.js
Kevin McIntyre d9e84812ff Initial release: Go Jdenticon library v0.1.0
- Core library with SVG and PNG generation
- CLI tool with generate and batch commands
- Cross-platform path handling for Windows compatibility
- Comprehensive test suite with integration tests
2026-01-03 23:41:48 -05:00

140 lines
4.5 KiB
JavaScript

#!/usr/bin/env node
/**
* Node.js benchmark script for jdenticon-js using perf_hooks
* Tests performance with JIT warm-up for fair comparison against Go implementation
* Run with: node --expose-gc benchmark-js.js
*/
const fs = require('fs');
const path = require('path');
const { performance } = require('perf_hooks');
// Check if jdenticon-js is available
let jdenticon;
try {
jdenticon = require('../jdenticon-js/dist/jdenticon-node.js');
} catch (err) {
console.error('Error: jdenticon-js not found. Please ensure it\'s available in jdenticon-js/dist/');
console.error('You may need to build the JS version first.');
process.exit(1);
}
// --- Configuration ---
const ICON_SIZE = 64;
const WARMUP_RUNS = 3;
// Load test inputs
const inputsPath = path.join(__dirname, 'inputs.json');
if (!fs.existsSync(inputsPath)) {
console.error('Error: inputs.json not found. Run generate-inputs.js first.');
process.exit(1);
}
const inputs = JSON.parse(fs.readFileSync(inputsPath, 'utf8'));
const numInputs = inputs.length;
console.log('=== jdenticon-js Performance Benchmark ===');
console.log(`Inputs: ${numInputs} unique hash strings`);
console.log(`Icon size: ${ICON_SIZE}x${ICON_SIZE} pixels`);
console.log(`Format: SVG`);
console.log(`Node.js version: ${process.version}`);
console.log(`V8 version: ${process.versions.v8}`);
console.log('');
// --- Benchmark Function ---
function generateAllIcons() {
for (let i = 0; i < numInputs; i++) {
jdenticon.toSvg(inputs[i], ICON_SIZE);
}
}
// --- Warm-up Phase ---
console.log(`Warming up JIT with ${WARMUP_RUNS} runs...`);
for (let i = 0; i < WARMUP_RUNS; i++) {
console.log(` Warm-up run ${i + 1}/${WARMUP_RUNS}`);
generateAllIcons();
}
// Force garbage collection for clean baseline (if --expose-gc was used)
if (global.gc) {
console.log('Forcing garbage collection...');
global.gc();
} else {
console.log('Note: Run with --expose-gc for more accurate memory measurements');
}
console.log('');
// --- Measurement Phase ---
console.log(`Running benchmark with ${numInputs} icons...`);
const memBefore = process.memoryUsage();
const startTime = performance.now();
generateAllIcons(); // The actual benchmark run
const endTime = performance.now();
const memAfter = process.memoryUsage();
// --- Calculate Metrics ---
const totalTimeMs = endTime - startTime;
const timePerIconMs = totalTimeMs / numInputs;
const timePerIconUs = timePerIconMs * 1000; // microseconds
const iconsPerSecond = 1000 / timePerIconMs;
// Memory metrics
const heapDelta = memAfter.heapUsed - memBefore.heapUsed;
const heapDeltaKB = heapDelta / 1024;
const heapDeltaPerIcon = heapDelta / numInputs;
// --- Results Report ---
console.log('');
console.log('=== jdenticon-js Results ===');
console.log(`Total time: ${totalTimeMs.toFixed(2)} ms`);
console.log(`Time per icon: ${timePerIconMs.toFixed(4)} ms (${timePerIconUs.toFixed(2)} μs)`);
console.log(`Throughput: ${iconsPerSecond.toFixed(2)} icons/sec`);
console.log('');
console.log('Memory Usage:');
console.log(` Heap before: ${(memBefore.heapUsed / 1024).toFixed(2)} KB`);
console.log(` Heap after: ${(memAfter.heapUsed / 1024).toFixed(2)} KB`);
console.log(` Heap delta: ${heapDeltaKB.toFixed(2)} KB`);
console.log(` Per icon: ${heapDeltaPerIcon.toFixed(2)} bytes`);
console.log('');
console.log('Additional Memory Info:');
console.log(` RSS: ${(memAfter.rss / 1024 / 1024).toFixed(2)} MB`);
console.log(` External: ${(memAfter.external / 1024).toFixed(2)} KB`);
// --- Save Results for Comparison ---
const results = {
implementation: 'jdenticon-js',
timestamp: new Date().toISOString(),
nodeVersion: process.version,
v8Version: process.versions.v8,
config: {
iconSize: ICON_SIZE,
numInputs: numInputs,
warmupRuns: WARMUP_RUNS
},
performance: {
totalTimeMs: totalTimeMs,
timePerIconMs: timePerIconMs,
timePerIconUs: timePerIconUs,
iconsPerSecond: iconsPerSecond
},
memory: {
heapBeforeKB: memBefore.heapUsed / 1024,
heapAfterKB: memAfter.heapUsed / 1024,
heapDeltaKB: heapDeltaKB,
heapDeltaPerIcon: heapDeltaPerIcon,
rssKB: memAfter.rss / 1024,
externalKB: memAfter.external / 1024
}
};
const resultsPath = path.join(__dirname, 'results-js.json');
fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2));
console.log(`Results saved to: ${resultsPath}`);
console.log('');
console.log('Run Go benchmark next: go test -bench=BenchmarkGenerate64pxIcon -benchmem ./...');