@sparkleideas/performance 3.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +256 -0
- package/__tests__/README.md +242 -0
- package/__tests__/attention.test.ts +516 -0
- package/__tests__/benchmarks.test.ts +515 -0
- package/benchmarks/attention/memory-efficiency.bench.ts +569 -0
- package/benchmarks/attention/multi-head-attention.bench.ts +566 -0
- package/benchmarks/startup/agent-spawn.bench.ts +422 -0
- package/benchmarks/startup/cli-cold-start.bench.ts +327 -0
- package/benchmarks/startup/cli-warm-start.bench.ts +277 -0
- package/benchmarks/startup/mcp-server-init.bench.ts +380 -0
- package/docs/ATTENTION.md +277 -0
- package/package.json +29 -0
- package/src/attention-benchmarks.ts +459 -0
- package/src/attention-integration.ts +507 -0
- package/src/examples/flash-attention-demo.ts +160 -0
- package/src/examples/quick-test.ts +62 -0
- package/src/framework/benchmark.ts +583 -0
- package/src/index.ts +63 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +31 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Quick Integration Test
|
|
4
|
+
*
|
|
5
|
+
* Verifies @ruvector/attention integration is working correctly.
|
|
6
|
+
* Run with: npx tsx v3/@sparkleideas/performance/src/examples/quick-test.ts
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { FlashAttention } from '@ruvector/attention';
|
|
10
|
+
import {
|
|
11
|
+
createFlashAttentionOptimizer,
|
|
12
|
+
quickBenchmark,
|
|
13
|
+
} from '../attention-integration.js';
|
|
14
|
+
|
|
15
|
+
async function quickTest() {
|
|
16
|
+
console.log('\n๐งช Quick Integration Test\n');
|
|
17
|
+
console.log('โ'.repeat(60));
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
// Test 1: Direct @ruvector/attention usage
|
|
21
|
+
console.log('\nโ Test 1: Direct @ruvector/attention usage');
|
|
22
|
+
const flash = new FlashAttention(128, 64); // dim, blockSize
|
|
23
|
+
const query = new Float32Array(128).fill(1.0);
|
|
24
|
+
const keys = [new Float32Array(128).fill(1.0)];
|
|
25
|
+
const values = [new Float32Array(128).fill(1.0)];
|
|
26
|
+
const result = flash.compute(query, keys, values);
|
|
27
|
+
console.log(` Result: Float32Array[${result.length}]`);
|
|
28
|
+
|
|
29
|
+
// Test 2: V3 optimizer
|
|
30
|
+
console.log('\nโ Test 2: V3 FlashAttentionOptimizer');
|
|
31
|
+
const optimizer = createFlashAttentionOptimizer(128);
|
|
32
|
+
const output = optimizer.optimize({
|
|
33
|
+
query: new Float32Array(128).fill(1.0),
|
|
34
|
+
keys: Array.from({ length: 50 }, () => new Float32Array(128).fill(1.0)),
|
|
35
|
+
values: Array.from({ length: 50 }, () => new Float32Array(128).fill(1.0)),
|
|
36
|
+
});
|
|
37
|
+
console.log(` Execution time: ${output.executionTimeMs.toFixed(3)}ms`);
|
|
38
|
+
console.log(` Runtime: ${output.runtime}`);
|
|
39
|
+
|
|
40
|
+
// Test 3: Quick benchmark
|
|
41
|
+
console.log('\nโ Test 3: Quick benchmark');
|
|
42
|
+
const benchResult = quickBenchmark(256);
|
|
43
|
+
console.log(` Flash: ${benchResult.flashAttention.averageTimeMs.toFixed(3)}ms`);
|
|
44
|
+
console.log(` Baseline: ${benchResult.baseline.averageTimeMs.toFixed(3)}ms`);
|
|
45
|
+
console.log(` Speedup: ${benchResult.speedup.toFixed(2)}x`);
|
|
46
|
+
console.log(` Meets target: ${benchResult.meetsTarget ? 'YES โ' : 'NO โ'}`);
|
|
47
|
+
|
|
48
|
+
console.log('\n' + 'โ'.repeat(60));
|
|
49
|
+
console.log('\nโ
All tests passed! Integration working correctly.\n');
|
|
50
|
+
|
|
51
|
+
return true;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('\nโ Test failed:', error);
|
|
54
|
+
console.log('\n' + 'โ'.repeat(60) + '\n');
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Run test
|
|
60
|
+
quickTest().then(success => {
|
|
61
|
+
process.exit(success ? 0 : 1);
|
|
62
|
+
});
|
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V3 Performance Benchmark Framework
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive benchmarking system with statistical analysis,
|
|
5
|
+
* memory tracking, and regression detection capabilities.
|
|
6
|
+
*
|
|
7
|
+
* Target Performance Metrics:
|
|
8
|
+
* - CLI Startup: <500ms (5x faster)
|
|
9
|
+
* - MCP Init: <400ms (4.5x faster)
|
|
10
|
+
* - Agent Spawn: <200ms (4x faster)
|
|
11
|
+
* - Vector Search: <1ms (150x faster)
|
|
12
|
+
* - Memory Write: <5ms (10x faster)
|
|
13
|
+
* - Swarm Consensus: <100ms (5x faster)
|
|
14
|
+
* - Flash Attention: 2.49x-7.47x speedup
|
|
15
|
+
* - Memory Usage: <256MB (50% reduction)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { performance, PerformanceObserver } from 'perf_hooks';
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Types and Interfaces
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
export interface MemoryUsage {
|
|
25
|
+
heapUsed: number;
|
|
26
|
+
heapTotal: number;
|
|
27
|
+
external: number;
|
|
28
|
+
arrayBuffers: number;
|
|
29
|
+
rss: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface BenchmarkResult {
|
|
33
|
+
name: string;
|
|
34
|
+
iterations: number;
|
|
35
|
+
mean: number;
|
|
36
|
+
median: number;
|
|
37
|
+
p95: number;
|
|
38
|
+
p99: number;
|
|
39
|
+
min: number;
|
|
40
|
+
max: number;
|
|
41
|
+
stdDev: number;
|
|
42
|
+
opsPerSecond: number;
|
|
43
|
+
memoryUsage: MemoryUsage;
|
|
44
|
+
memoryDelta: number;
|
|
45
|
+
timestamp: number;
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface BenchmarkOptions {
|
|
50
|
+
/** Number of iterations (default: 100) */
|
|
51
|
+
iterations?: number;
|
|
52
|
+
/** Number of warmup iterations (default: 10) */
|
|
53
|
+
warmup?: number;
|
|
54
|
+
/** Timeout per iteration in ms (default: 30000) */
|
|
55
|
+
timeout?: number;
|
|
56
|
+
/** Force garbage collection between iterations */
|
|
57
|
+
forceGC?: boolean;
|
|
58
|
+
/** Custom metadata to attach to results */
|
|
59
|
+
metadata?: Record<string, unknown>;
|
|
60
|
+
/** Minimum number of runs to ensure statistical significance */
|
|
61
|
+
minRuns?: number;
|
|
62
|
+
/** Target time in ms for auto-calibration */
|
|
63
|
+
targetTime?: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface BenchmarkSuite {
|
|
67
|
+
name: string;
|
|
68
|
+
benchmarks: BenchmarkResult[];
|
|
69
|
+
totalTime: number;
|
|
70
|
+
timestamp: number;
|
|
71
|
+
environment: EnvironmentInfo;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface EnvironmentInfo {
|
|
75
|
+
nodeVersion: string;
|
|
76
|
+
platform: string;
|
|
77
|
+
arch: string;
|
|
78
|
+
cpus: number;
|
|
79
|
+
memory: number;
|
|
80
|
+
v8Version?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ComparisonResult {
|
|
84
|
+
benchmark: string;
|
|
85
|
+
baseline: number;
|
|
86
|
+
current: number;
|
|
87
|
+
change: number;
|
|
88
|
+
changePercent: number;
|
|
89
|
+
improved: boolean;
|
|
90
|
+
significant: boolean;
|
|
91
|
+
target?: number;
|
|
92
|
+
targetMet: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// Statistical Functions
|
|
97
|
+
// ============================================================================
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Calculate mean of an array of numbers
|
|
101
|
+
*/
|
|
102
|
+
function calculateMean(values: number[]): number {
|
|
103
|
+
if (values.length === 0) return 0;
|
|
104
|
+
return values.reduce((sum, val) => sum + val, 0) / values.length;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Calculate median of an array of numbers
|
|
109
|
+
*/
|
|
110
|
+
function calculateMedian(values: number[]): number {
|
|
111
|
+
if (values.length === 0) return 0;
|
|
112
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
113
|
+
const mid = Math.floor(sorted.length / 2);
|
|
114
|
+
return sorted.length % 2 !== 0
|
|
115
|
+
? sorted[mid]!
|
|
116
|
+
: (sorted[mid - 1]! + sorted[mid]!) / 2;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Calculate percentile of an array of numbers
|
|
121
|
+
*/
|
|
122
|
+
function calculatePercentile(values: number[], percentile: number): number {
|
|
123
|
+
if (values.length === 0) return 0;
|
|
124
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
125
|
+
const index = Math.ceil((percentile / 100) * sorted.length) - 1;
|
|
126
|
+
return sorted[Math.max(0, index)]!;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Calculate standard deviation of an array of numbers
|
|
131
|
+
*/
|
|
132
|
+
function calculateStdDev(values: number[]): number {
|
|
133
|
+
if (values.length < 2) return 0;
|
|
134
|
+
const mean = calculateMean(values);
|
|
135
|
+
const squaredDiffs = values.map((val) => Math.pow(val - mean, 2));
|
|
136
|
+
return Math.sqrt(calculateMean(squaredDiffs));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Remove outliers using IQR method
|
|
141
|
+
*/
|
|
142
|
+
function removeOutliers(values: number[]): number[] {
|
|
143
|
+
if (values.length < 4) return values;
|
|
144
|
+
|
|
145
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
146
|
+
const q1 = calculatePercentile(sorted, 25);
|
|
147
|
+
const q3 = calculatePercentile(sorted, 75);
|
|
148
|
+
const iqr = q3 - q1;
|
|
149
|
+
const lowerBound = q1 - 1.5 * iqr;
|
|
150
|
+
const upperBound = q3 + 1.5 * iqr;
|
|
151
|
+
|
|
152
|
+
return sorted.filter((val) => val >= lowerBound && val <= upperBound);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ============================================================================
|
|
156
|
+
// Memory Utilities
|
|
157
|
+
// ============================================================================
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get current memory usage
|
|
161
|
+
*/
|
|
162
|
+
function getMemoryUsage(): MemoryUsage {
|
|
163
|
+
const mem = process.memoryUsage();
|
|
164
|
+
return {
|
|
165
|
+
heapUsed: mem.heapUsed,
|
|
166
|
+
heapTotal: mem.heapTotal,
|
|
167
|
+
external: mem.external,
|
|
168
|
+
arrayBuffers: mem.arrayBuffers,
|
|
169
|
+
rss: mem.rss,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Format bytes to human-readable string
|
|
175
|
+
*/
|
|
176
|
+
export function formatBytes(bytes: number): string {
|
|
177
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
178
|
+
let unitIndex = 0;
|
|
179
|
+
let value = bytes;
|
|
180
|
+
|
|
181
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
182
|
+
value /= 1024;
|
|
183
|
+
unitIndex++;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return `${value.toFixed(2)} ${units[unitIndex]}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Format time in milliseconds to human-readable string
|
|
191
|
+
*/
|
|
192
|
+
export function formatTime(ms: number): string {
|
|
193
|
+
if (ms < 0.001) {
|
|
194
|
+
return `${(ms * 1000000).toFixed(2)} ns`;
|
|
195
|
+
} else if (ms < 1) {
|
|
196
|
+
return `${(ms * 1000).toFixed(2)} us`;
|
|
197
|
+
} else if (ms < 1000) {
|
|
198
|
+
return `${ms.toFixed(2)} ms`;
|
|
199
|
+
} else {
|
|
200
|
+
return `${(ms / 1000).toFixed(2)} s`;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Force garbage collection if available
|
|
206
|
+
*/
|
|
207
|
+
function forceGC(): void {
|
|
208
|
+
if (typeof global.gc === 'function') {
|
|
209
|
+
global.gc();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ============================================================================
|
|
214
|
+
// Core Benchmark Function
|
|
215
|
+
// ============================================================================
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Execute a benchmark with comprehensive statistics
|
|
219
|
+
*/
|
|
220
|
+
export async function benchmark(
|
|
221
|
+
name: string,
|
|
222
|
+
fn: () => Promise<void> | void,
|
|
223
|
+
options: BenchmarkOptions = {}
|
|
224
|
+
): Promise<BenchmarkResult> {
|
|
225
|
+
const {
|
|
226
|
+
iterations = 100,
|
|
227
|
+
warmup = 10,
|
|
228
|
+
timeout = 30000,
|
|
229
|
+
forceGC: doForceGC = false,
|
|
230
|
+
metadata = {},
|
|
231
|
+
minRuns = 10,
|
|
232
|
+
targetTime = 1000,
|
|
233
|
+
} = options;
|
|
234
|
+
|
|
235
|
+
// Calculate actual iterations based on target time
|
|
236
|
+
let actualIterations = iterations;
|
|
237
|
+
|
|
238
|
+
// Warmup phase
|
|
239
|
+
for (let i = 0; i < warmup; i++) {
|
|
240
|
+
await Promise.race([
|
|
241
|
+
fn(),
|
|
242
|
+
new Promise((_, reject) =>
|
|
243
|
+
setTimeout(() => reject(new Error('Warmup timeout')), timeout)
|
|
244
|
+
),
|
|
245
|
+
]).catch(() => {});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Auto-calibrate iterations if needed
|
|
249
|
+
const calibrationStart = performance.now();
|
|
250
|
+
await fn();
|
|
251
|
+
const calibrationTime = performance.now() - calibrationStart;
|
|
252
|
+
|
|
253
|
+
if (calibrationTime > 0) {
|
|
254
|
+
const estimatedIterations = Math.ceil(targetTime / calibrationTime);
|
|
255
|
+
actualIterations = Math.max(minRuns, Math.min(iterations, estimatedIterations));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Memory before benchmark
|
|
259
|
+
if (doForceGC) forceGC();
|
|
260
|
+
const memoryBefore = getMemoryUsage();
|
|
261
|
+
|
|
262
|
+
// Run benchmark
|
|
263
|
+
const times: number[] = [];
|
|
264
|
+
const startTime = performance.now();
|
|
265
|
+
|
|
266
|
+
for (let i = 0; i < actualIterations; i++) {
|
|
267
|
+
if (doForceGC && i % 10 === 0) forceGC();
|
|
268
|
+
|
|
269
|
+
const iterStart = performance.now();
|
|
270
|
+
|
|
271
|
+
await Promise.race([
|
|
272
|
+
fn(),
|
|
273
|
+
new Promise((_, reject) =>
|
|
274
|
+
setTimeout(() => reject(new Error('Iteration timeout')), timeout)
|
|
275
|
+
),
|
|
276
|
+
]);
|
|
277
|
+
|
|
278
|
+
const iterEnd = performance.now();
|
|
279
|
+
times.push(iterEnd - iterStart);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const totalTime = performance.now() - startTime;
|
|
283
|
+
|
|
284
|
+
// Memory after benchmark
|
|
285
|
+
const memoryAfter = getMemoryUsage();
|
|
286
|
+
|
|
287
|
+
// Calculate statistics (remove outliers for more accurate results)
|
|
288
|
+
const cleanedTimes = removeOutliers(times);
|
|
289
|
+
const mean = calculateMean(cleanedTimes);
|
|
290
|
+
const median = calculateMedian(cleanedTimes);
|
|
291
|
+
const p95 = calculatePercentile(cleanedTimes, 95);
|
|
292
|
+
const p99 = calculatePercentile(cleanedTimes, 99);
|
|
293
|
+
const min = Math.min(...cleanedTimes);
|
|
294
|
+
const max = Math.max(...cleanedTimes);
|
|
295
|
+
const stdDev = calculateStdDev(cleanedTimes);
|
|
296
|
+
const opsPerSecond = mean > 0 ? 1000 / mean : 0;
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
name,
|
|
300
|
+
iterations: actualIterations,
|
|
301
|
+
mean,
|
|
302
|
+
median,
|
|
303
|
+
p95,
|
|
304
|
+
p99,
|
|
305
|
+
min,
|
|
306
|
+
max,
|
|
307
|
+
stdDev,
|
|
308
|
+
opsPerSecond,
|
|
309
|
+
memoryUsage: memoryAfter,
|
|
310
|
+
memoryDelta: memoryAfter.heapUsed - memoryBefore.heapUsed,
|
|
311
|
+
timestamp: Date.now(),
|
|
312
|
+
metadata,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// ============================================================================
|
|
317
|
+
// Benchmark Suite Runner
|
|
318
|
+
// ============================================================================
|
|
319
|
+
|
|
320
|
+
export class BenchmarkRunner {
|
|
321
|
+
private results: BenchmarkResult[] = [];
|
|
322
|
+
private suiteName: string;
|
|
323
|
+
|
|
324
|
+
constructor(name: string) {
|
|
325
|
+
this.suiteName = name;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Run a single benchmark and add to results
|
|
330
|
+
*/
|
|
331
|
+
async run(
|
|
332
|
+
name: string,
|
|
333
|
+
fn: () => Promise<void> | void,
|
|
334
|
+
options?: BenchmarkOptions
|
|
335
|
+
): Promise<BenchmarkResult> {
|
|
336
|
+
const result = await benchmark(name, fn, options);
|
|
337
|
+
this.results.push(result);
|
|
338
|
+
return result;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Run multiple benchmarks in sequence
|
|
343
|
+
*/
|
|
344
|
+
async runAll(
|
|
345
|
+
benchmarks: Array<{
|
|
346
|
+
name: string;
|
|
347
|
+
fn: () => Promise<void> | void;
|
|
348
|
+
options?: BenchmarkOptions;
|
|
349
|
+
}>
|
|
350
|
+
): Promise<BenchmarkSuite> {
|
|
351
|
+
const startTime = performance.now();
|
|
352
|
+
|
|
353
|
+
for (const bench of benchmarks) {
|
|
354
|
+
await this.run(bench.name, bench.fn, bench.options);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
name: this.suiteName,
|
|
359
|
+
benchmarks: this.results,
|
|
360
|
+
totalTime: performance.now() - startTime,
|
|
361
|
+
timestamp: Date.now(),
|
|
362
|
+
environment: this.getEnvironmentInfo(),
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Get environment information
|
|
368
|
+
*/
|
|
369
|
+
private getEnvironmentInfo(): EnvironmentInfo {
|
|
370
|
+
const os = require('os');
|
|
371
|
+
return {
|
|
372
|
+
nodeVersion: process.version,
|
|
373
|
+
platform: process.platform,
|
|
374
|
+
arch: process.arch,
|
|
375
|
+
cpus: os.cpus().length,
|
|
376
|
+
memory: os.totalmem(),
|
|
377
|
+
v8Version: process.versions.v8,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Get all results
|
|
383
|
+
*/
|
|
384
|
+
getResults(): BenchmarkResult[] {
|
|
385
|
+
return this.results;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Clear all results
|
|
390
|
+
*/
|
|
391
|
+
clear(): void {
|
|
392
|
+
this.results = [];
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Print formatted results to console
|
|
397
|
+
*/
|
|
398
|
+
printResults(): void {
|
|
399
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
400
|
+
console.log(`Benchmark Suite: ${this.suiteName}`);
|
|
401
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
402
|
+
|
|
403
|
+
for (const result of this.results) {
|
|
404
|
+
console.log(`${result.name}:`);
|
|
405
|
+
console.log(` Iterations: ${result.iterations}`);
|
|
406
|
+
console.log(` Mean: ${formatTime(result.mean)}`);
|
|
407
|
+
console.log(` Median: ${formatTime(result.median)}`);
|
|
408
|
+
console.log(` Std Dev: ${formatTime(result.stdDev)}`);
|
|
409
|
+
console.log(` P95: ${formatTime(result.p95)}`);
|
|
410
|
+
console.log(` P99: ${formatTime(result.p99)}`);
|
|
411
|
+
console.log(` Min: ${formatTime(result.min)}`);
|
|
412
|
+
console.log(` Max: ${formatTime(result.max)}`);
|
|
413
|
+
console.log(` Ops/sec: ${result.opsPerSecond.toFixed(2)}`);
|
|
414
|
+
console.log(` Memory Delta: ${formatBytes(result.memoryDelta)}`);
|
|
415
|
+
console.log('');
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Export results as JSON
|
|
421
|
+
*/
|
|
422
|
+
toJSON(): string {
|
|
423
|
+
return JSON.stringify(
|
|
424
|
+
{
|
|
425
|
+
name: this.suiteName,
|
|
426
|
+
benchmarks: this.results,
|
|
427
|
+
timestamp: Date.now(),
|
|
428
|
+
environment: this.getEnvironmentInfo(),
|
|
429
|
+
},
|
|
430
|
+
null,
|
|
431
|
+
2
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// ============================================================================
|
|
437
|
+
// Comparison Utilities
|
|
438
|
+
// ============================================================================
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Compare benchmark results against baseline
|
|
442
|
+
*/
|
|
443
|
+
export function compareResults(
|
|
444
|
+
baseline: BenchmarkResult[],
|
|
445
|
+
current: BenchmarkResult[],
|
|
446
|
+
targets?: Record<string, number>
|
|
447
|
+
): ComparisonResult[] {
|
|
448
|
+
const comparisons: ComparisonResult[] = [];
|
|
449
|
+
|
|
450
|
+
for (const curr of current) {
|
|
451
|
+
const base = baseline.find((b) => b.name === curr.name);
|
|
452
|
+
if (!base) continue;
|
|
453
|
+
|
|
454
|
+
const change = curr.mean - base.mean;
|
|
455
|
+
const changePercent = (change / base.mean) * 100;
|
|
456
|
+
const improved = change < 0;
|
|
457
|
+
|
|
458
|
+
// Consider significant if change is > 5% and > 2 standard deviations
|
|
459
|
+
const combinedStdDev = Math.sqrt(
|
|
460
|
+
Math.pow(base.stdDev, 2) + Math.pow(curr.stdDev, 2)
|
|
461
|
+
);
|
|
462
|
+
const significant = Math.abs(change) > 2 * combinedStdDev;
|
|
463
|
+
|
|
464
|
+
const target = targets?.[curr.name];
|
|
465
|
+
const targetMet = target !== undefined ? curr.mean <= target : true;
|
|
466
|
+
|
|
467
|
+
comparisons.push({
|
|
468
|
+
benchmark: curr.name,
|
|
469
|
+
baseline: base.mean,
|
|
470
|
+
current: curr.mean,
|
|
471
|
+
change,
|
|
472
|
+
changePercent,
|
|
473
|
+
improved,
|
|
474
|
+
significant,
|
|
475
|
+
target,
|
|
476
|
+
targetMet,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return comparisons;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Print comparison report
|
|
485
|
+
*/
|
|
486
|
+
export function printComparisonReport(comparisons: ComparisonResult[]): void {
|
|
487
|
+
console.log('\n' + '='.repeat(80));
|
|
488
|
+
console.log('Performance Comparison Report');
|
|
489
|
+
console.log('='.repeat(80) + '\n');
|
|
490
|
+
|
|
491
|
+
console.log(
|
|
492
|
+
`${'Benchmark'.padEnd(35)} ${'Baseline'.padEnd(12)} ${'Current'.padEnd(12)} ${'Change'.padEnd(12)} Status`
|
|
493
|
+
);
|
|
494
|
+
console.log('-'.repeat(80));
|
|
495
|
+
|
|
496
|
+
for (const comp of comparisons) {
|
|
497
|
+
const baselineStr = formatTime(comp.baseline);
|
|
498
|
+
const currentStr = formatTime(comp.current);
|
|
499
|
+
const changeStr = `${comp.changePercent >= 0 ? '+' : ''}${comp.changePercent.toFixed(1)}%`;
|
|
500
|
+
|
|
501
|
+
let status = '';
|
|
502
|
+
if (comp.significant) {
|
|
503
|
+
status = comp.improved ? '[IMPROVED]' : '[REGRESSED]';
|
|
504
|
+
} else {
|
|
505
|
+
status = '[~]';
|
|
506
|
+
}
|
|
507
|
+
if (!comp.targetMet) {
|
|
508
|
+
status += ' [MISSED TARGET]';
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
console.log(
|
|
512
|
+
`${comp.benchmark.padEnd(35)} ${baselineStr.padEnd(12)} ${currentStr.padEnd(12)} ${changeStr.padEnd(12)} ${status}`
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
console.log('\n');
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// ============================================================================
|
|
520
|
+
// V3 Performance Targets
|
|
521
|
+
// ============================================================================
|
|
522
|
+
|
|
523
|
+
export const V3_PERFORMANCE_TARGETS = {
|
|
524
|
+
// Startup Performance
|
|
525
|
+
'cli-cold-start': 500, // <500ms (5x faster)
|
|
526
|
+
'cli-warm-start': 100, // <100ms
|
|
527
|
+
'mcp-server-init': 400, // <400ms (4.5x faster)
|
|
528
|
+
'agent-spawn': 200, // <200ms (4x faster)
|
|
529
|
+
|
|
530
|
+
// Memory Operations
|
|
531
|
+
'vector-search': 1, // <1ms (150x faster)
|
|
532
|
+
'hnsw-indexing': 10, // <10ms
|
|
533
|
+
'memory-write': 5, // <5ms (10x faster)
|
|
534
|
+
'cache-hit': 0.1, // <0.1ms
|
|
535
|
+
|
|
536
|
+
// Swarm Coordination
|
|
537
|
+
'agent-coordination': 50, // <50ms
|
|
538
|
+
'task-decomposition': 20, // <20ms
|
|
539
|
+
'consensus-latency': 100, // <100ms (5x faster)
|
|
540
|
+
'message-throughput': 0.1, // <0.1ms per message
|
|
541
|
+
|
|
542
|
+
// Attention Mechanisms
|
|
543
|
+
'flash-attention': 100, // Baseline comparison target
|
|
544
|
+
'multi-head-attention': 200, // Baseline comparison target
|
|
545
|
+
|
|
546
|
+
// SONA Learning
|
|
547
|
+
'sona-adaptation': 0.05, // <0.05ms
|
|
548
|
+
} as const;
|
|
549
|
+
|
|
550
|
+
export type PerformanceTarget = keyof typeof V3_PERFORMANCE_TARGETS;
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Check if a benchmark meets its target
|
|
554
|
+
*/
|
|
555
|
+
export function meetsTarget(
|
|
556
|
+
benchmarkName: string,
|
|
557
|
+
value: number
|
|
558
|
+
): { met: boolean; target: number | undefined; ratio: number | undefined } {
|
|
559
|
+
const target = V3_PERFORMANCE_TARGETS[benchmarkName as PerformanceTarget];
|
|
560
|
+
if (target === undefined) {
|
|
561
|
+
return { met: true, target: undefined, ratio: undefined };
|
|
562
|
+
}
|
|
563
|
+
return {
|
|
564
|
+
met: value <= target,
|
|
565
|
+
target,
|
|
566
|
+
ratio: value / target,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// ============================================================================
|
|
571
|
+
// Export Default Runner Instance
|
|
572
|
+
// ============================================================================
|
|
573
|
+
|
|
574
|
+
export default {
|
|
575
|
+
benchmark,
|
|
576
|
+
BenchmarkRunner,
|
|
577
|
+
compareResults,
|
|
578
|
+
printComparisonReport,
|
|
579
|
+
formatBytes,
|
|
580
|
+
formatTime,
|
|
581
|
+
meetsTarget,
|
|
582
|
+
V3_PERFORMANCE_TARGETS,
|
|
583
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sparkleideas/performance
|
|
3
|
+
*
|
|
4
|
+
* Performance module for @sparkleideas/claude-flow v3.
|
|
5
|
+
* Provides benchmarking, Flash Attention validation, and optimization utilities.
|
|
6
|
+
*
|
|
7
|
+
* Target Performance Metrics:
|
|
8
|
+
* - CLI Startup: <500ms (5x faster)
|
|
9
|
+
* - MCP Init: <400ms (4.5x faster)
|
|
10
|
+
* - Agent Spawn: <200ms (4x faster)
|
|
11
|
+
* - Vector Search: <1ms (150x faster)
|
|
12
|
+
* - Memory Write: <5ms (10x faster)
|
|
13
|
+
* - Swarm Consensus: <100ms (5x faster)
|
|
14
|
+
* - Flash Attention: 2.49x-7.47x speedup
|
|
15
|
+
* - Memory Usage: <256MB (50% reduction)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// Re-export benchmark framework
|
|
19
|
+
export {
|
|
20
|
+
benchmark,
|
|
21
|
+
BenchmarkRunner,
|
|
22
|
+
compareResults,
|
|
23
|
+
printComparisonReport,
|
|
24
|
+
formatBytes,
|
|
25
|
+
formatTime,
|
|
26
|
+
meetsTarget,
|
|
27
|
+
V3_PERFORMANCE_TARGETS,
|
|
28
|
+
type BenchmarkResult,
|
|
29
|
+
type BenchmarkOptions,
|
|
30
|
+
type BenchmarkSuite,
|
|
31
|
+
type EnvironmentInfo,
|
|
32
|
+
type ComparisonResult,
|
|
33
|
+
type MemoryUsage,
|
|
34
|
+
type PerformanceTarget,
|
|
35
|
+
} from './framework/benchmark.js';
|
|
36
|
+
|
|
37
|
+
// Re-export Flash Attention integration
|
|
38
|
+
export {
|
|
39
|
+
FlashAttentionOptimizer,
|
|
40
|
+
createFlashAttentionOptimizer,
|
|
41
|
+
quickBenchmark,
|
|
42
|
+
type AttentionInput,
|
|
43
|
+
type AttentionOutput,
|
|
44
|
+
type BenchmarkResult as AttentionBenchmarkResult,
|
|
45
|
+
type PerformanceMetrics as AttentionMetrics,
|
|
46
|
+
} from './attention-integration.js';
|
|
47
|
+
|
|
48
|
+
// Re-export Flash Attention benchmarks
|
|
49
|
+
export {
|
|
50
|
+
AttentionBenchmarkRunner,
|
|
51
|
+
formatBenchmarkTable,
|
|
52
|
+
formatSuiteReport,
|
|
53
|
+
formatMemoryProfile,
|
|
54
|
+
quickValidation,
|
|
55
|
+
runAndDisplaySuite,
|
|
56
|
+
runAndDisplayMemoryProfile,
|
|
57
|
+
type ComparisonBenchmark,
|
|
58
|
+
type SuiteResult,
|
|
59
|
+
type MemoryProfile,
|
|
60
|
+
} from './attention-benchmarks.js';
|
|
61
|
+
|
|
62
|
+
// Default export for convenience
|
|
63
|
+
export { default } from './framework/benchmark.js';
|
package/tmp.json
ADDED
|
File without changes
|