mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 07:51:52 +00:00
perf: parallelize daily/weekly lock queries in list command
- Modified `src/lib.mjs` to execute `queryLocks` for all cadences in parallel. - Added `scripts/perf-benchmark.mjs` for measuring CLI performance. - Added `weekly-perf-report-2026-02-14.md` with baseline and verification data. - Added `task-logs/weekly/2026-02-14T13-14-38Z__perf-deepdive-agent__completed.md`. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
c731f2b09d
commit
9716fe3812
6 files changed
+147
-1
No files matched your search
@@ -0,0 +1,12 @@
|
||||
Benchmarking "node bin/torch-lock.mjs list" (5 iterations)...
|
||||
Run 1: 15199.04ms
|
||||
Run 2: 15186.28ms
|
||||
Run 3: 15188.74ms
|
||||
Run 4: 15191.66ms
|
||||
Run 5: 15184.86ms
|
||||
|
||||
Results:
|
||||
Count: 5
|
||||
Average: 15190.12ms
|
||||
Min: 15184.86ms
|
||||
Max: 15199.04ms
|
||||
@@ -0,0 +1,12 @@
|
||||
Benchmarking "node bin/torch-lock.mjs list" (5 iterations)...
|
||||
Run 1: 15775.77ms
|
||||
Run 2: 15773.07ms
|
||||
Run 3: 15800.54ms
|
||||
Run 4: 15770.65ms
|
||||
Run 5: 16013.24ms
|
||||
|
||||
Results:
|
||||
Count: 5
|
||||
Average: 15826.65ms
|
||||
Min: 15770.65ms
|
||||
Max: 16013.24ms
|
||||
@@ -0,0 +1,57 @@
|
||||
import { spawn } from 'node:child_process';
|
||||
import { performance } from 'node:perf_hooks';
|
||||
|
||||
const ITERATIONS = 5;
|
||||
const COMMAND = 'node';
|
||||
const ARGS = ['bin/torch-lock.mjs', 'list'];
|
||||
|
||||
async function runOnce(i) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const start = performance.now();
|
||||
const child = spawn(COMMAND, ARGS, { stdio: 'ignore' });
|
||||
|
||||
child.on('close', (code) => {
|
||||
const duration = performance.now() - start;
|
||||
if (code === 0) {
|
||||
console.log(`Run ${i + 1}: ${duration.toFixed(2)}ms`);
|
||||
resolve(duration);
|
||||
} else {
|
||||
reject(new Error(`Process exited with code ${code}`));
|
||||
}
|
||||
});
|
||||
|
||||
child.on('error', (err) => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log(`Benchmarking "${COMMAND} ${ARGS.join(' ')}" (${ITERATIONS} iterations)...`);
|
||||
const times = [];
|
||||
|
||||
for (let i = 0; i < ITERATIONS; i++) {
|
||||
try {
|
||||
const duration = await runOnce(i);
|
||||
times.push(duration);
|
||||
} catch (err) {
|
||||
console.error(`Run ${i + 1} failed:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
if (times.length === 0) {
|
||||
console.error('No successful runs.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const sum = times.reduce((a, b) => a + b, 0);
|
||||
const avg = sum / times.length;
|
||||
const min = Math.min(...times);
|
||||
const max = Math.max(...times);
|
||||
|
||||
console.log('\nResults:');
|
||||
console.log(` Count: ${times.length}`);
|
||||
console.log(` Average: ${avg.toFixed(2)}ms`);
|
||||
console.log(` Min: ${min.toFixed(2)}ms`);
|
||||
console.log(` Max: ${max.toFixed(2)}ms`);
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
+6
-1
@@ -439,9 +439,14 @@ export async function cmdList(cadence) {
|
||||
|
||||
console.error(`Listing active locks: namespace=${namespace}, cadences=${cadences.join(', ')}`);
|
||||
|
||||
for (const c of cadences) {
|
||||
const results = await Promise.all(
|
||||
cadences.map(async (c) => {
|
||||
const locks = await queryLocks(relays, c, dateStr, namespace);
|
||||
return { c, locks };
|
||||
}),
|
||||
);
|
||||
|
||||
for (const { c, locks } of results) {
|
||||
console.log(`\n${'='.repeat(72)}`);
|
||||
console.log(`Active ${namespace} ${c} locks (${dateStr})`);
|
||||
console.log('='.repeat(72));
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
agent: perf-deepdive-agent
|
||||
status: completed
|
||||
date: 2026-02-14
|
||||
---
|
||||
|
||||
# Weekly Performance Deep Dive
|
||||
|
||||
## Summary
|
||||
- **Scenario**: Listing active locks (`torch-lock list`), which involves querying relays for both daily and weekly cadences.
|
||||
- **Optimization**: Parallelized the relay queries in `src/lib.mjs`.
|
||||
- **Baseline Duration**: ~15.8s
|
||||
- **Post-Optimization Duration**: ~15.2s
|
||||
- **Improvement**: ~4%
|
||||
|
||||
## Analysis
|
||||
The performance is dominated by a 15s timeout on one of the queries. Parallelization ensures that the total duration is determined by the slowest query, rather than the sum of sequential query times (which would be ~30s if both timed out).
|
||||
|
||||
## Artifacts
|
||||
- `weekly-perf-report-2026-02-14.md`: Detailed report with benchmark data.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Weekly Performance Report - 2026-02-14
|
||||
|
||||
## Scenario
|
||||
Running `node bin/torch-lock.mjs list` to list active locks for both daily and weekly cadences.
|
||||
This command executes two sequential queries to Nostr relays.
|
||||
|
||||
## Baseline (Before Optimization)
|
||||
Measured using `scripts/perf-benchmark.mjs` (5 iterations).
|
||||
|
||||
- **Average Duration**: 15826.65ms
|
||||
- **Min Duration**: 15770.65ms
|
||||
- **Max Duration**: 16013.24ms
|
||||
|
||||
The command appears to be network-bound, likely due to sequential execution of relay queries for each cadence.
|
||||
|
||||
## After Optimization
|
||||
Modified `src/lib.mjs` to execute relay queries in parallel using `Promise.all`.
|
||||
|
||||
- **Average Duration**: 15190.12ms
|
||||
- **Min Duration**: 15184.86ms
|
||||
- **Max Duration**: 15199.04ms
|
||||
|
||||
## Analysis
|
||||
The speedup is approximately 4% (636ms).
|
||||
While theoretically this should parallelize the latency, the observed improvement is small.
|
||||
This suggests that either:
|
||||
1. The relays are responding very quickly but one query dominates the time (e.g. hitting a 15s timeout).
|
||||
2. The `SimplePool` instantiation overhead is significant.
|
||||
3. Network bandwidth or local resource contention limits the concurrency gains.
|
||||
|
||||
Given the timeout in `src/lib.mjs` is 15000ms, and the duration is just over 15000ms, it is highly likely that at least one query is timing out.
|
||||
If both queries were timing out sequentially, the duration would be ~30s.
|
||||
Since sequential was ~16s, it implies one query timed out (15s) and the other was very fast (<1s), OR they overlapped in some way (unlikely in sequential).
|
||||
|
||||
If one query takes 15s (timeout) and the other takes 0.5s:
|
||||
- Sequential: 15s + 0.5s = 15.5s.
|
||||
- Parallel: max(15s, 0.5s) = 15s.
|
||||
This matches the data perfectly.
|
||||
|
||||
Conclusion: One cadence query (likely 'daily' or 'weekly' specifically) is timing out or very slow, while the other is fast. Parallelization ensures we pay the "slowest" cost, not the sum.
|
||||
Reference in new issue
Block a user