1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
// benchmark-suite.js - Comprehensive performance benchmarking suite
import { benchmarkLexers } from './lexer-optimized.js';
import { benchmarkScopes } from './scope-stack.js';
import { benchmarkBuiltins } from './builtins-optimized.js';
import { benchmarkASTPool } from './ast-pool.js';
import { BabaYagaEngine } from './engine.js';
import { BabaYagaConfig } from './config.js';
/**
* Comprehensive benchmark suite for measuring performance improvements
*/
export class BenchmarkSuite {
constructor() {
this.results = {};
this.testPrograms = this.createTestPrograms();
}
/**
* Create test programs of varying complexity
*/
createTestPrograms() {
return {
simple: `
x : 42;
y : x + 8;
io.out y;
`,
arithmetic: `
add : x y -> x + y;
multiply : x y -> x * y;
result : multiply (add 10 20) (add 5 15);
io.out result;
`,
listProcessing: `
numbers : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
doubled : map (x -> x * 2) numbers;
evens : filter (x -> x % 2 = 0) doubled;
sum : reduce (acc x -> acc + x) 0 evens;
io.out sum;
`,
recursion: `
factorial : n ->
when n is
0 then 1
1 then 1
_ then n * (factorial (n - 1));
result : factorial 10;
io.out result;
`,
patternMatching: `
processValue : x ->
when x is
0 then "zero"
1 then "one"
Int then "integer"
String then "string"
_ then "other";
values : [0, 1, 42, "hello", true];
results : map processValue values;
io.out results;
`,
complexNested: `
fibonacci : n ->
when n is
0 then 0
1 then 1
_ then (fibonacci (n - 1)) + (fibonacci (n - 2));
range : n -> with rec (
helper : i acc ->
when i is
0 then acc
_ then helper (i - 1) (prepend i acc);
) -> helper n [];
fibNumbers : map fibonacci (range 15);
evenFibs : filter (x -> x % 2 = 0) fibNumbers;
result : reduce (acc x -> acc + x) 0 evenFibs;
io.out result;
`
};
}
/**
* Run all benchmarks
*/
async runAll() {
console.log('๐ Starting Baba Yaga Performance Benchmark Suite\n');
await this.benchmarkComponents();
await this.benchmarkPrograms();
await this.generateReport();
return this.results;
}
/**
* Benchmark individual components
*/
async benchmarkComponents() {
console.log('๐ Benchmarking Individual Components\n');
// Lexer benchmarks
console.log('๐ค Lexer Performance:');
this.results.lexer = await benchmarkLexers(this.testPrograms.complexNested, 1000);
console.log('');
// Scope stack benchmarks
console.log('๐ Scope Stack Performance:');
this.results.scopes = await benchmarkScopes(50000);
console.log('');
// Built-in functions benchmarks
console.log('โก Built-in Functions Performance:');
this.results.builtins = await benchmarkBuiltins(5000);
console.log('');
// AST Pool benchmarks
console.log('๐ AST Object Pool Performance:');
this.results.astPool = await benchmarkASTPool(50000);
console.log('');
}
/**
* Benchmark complete programs
*/
async benchmarkPrograms() {
console.log('๐ Benchmarking Complete Programs\n');
this.results.programs = {};
for (const [name, code] of Object.entries(this.testPrograms)) {
console.log(`๐งช Testing ${name}:`);
const result = await this.benchmarkProgram(code, name);
this.results.programs[name] = result;
console.log(` Original: ${result.originalTime.toFixed(2)}ms`);
console.log(` Optimized: ${result.optimizedTime.toFixed(2)}ms`);
console.log(` Speedup: ${result.speedup.toFixed(2)}x`);
console.log('');
}
}
/**
* Benchmark a single program with both engines
*/
async benchmarkProgram(code, name, iterations = 1000) {
// Benchmark original engine
const originalConfig = new BabaYagaConfig({
enableOptimizations: false,
enableDebugMode: false
});
const originalEngine = new BabaYagaEngine(originalConfig);
// Warm up
for (let i = 0; i < 10; i++) {
await originalEngine.execute(code);
}
const originalStart = performance.now();
for (let i = 0; i < iterations; i++) {
await originalEngine.execute(code);
}
const originalTime = performance.now() - originalStart;
// Benchmark optimized engine
const optimizedConfig = new BabaYagaConfig({
enableOptimizations: true,
enableDebugMode: false
});
const optimizedEngine = new BabaYagaEngine(optimizedConfig);
// Warm up
for (let i = 0; i < 10; i++) {
await optimizedEngine.execute(code);
}
const optimizedStart = performance.now();
for (let i = 0; i < iterations; i++) {
await optimizedEngine.execute(code);
}
const optimizedTime = performance.now() - optimizedStart;
return {
name,
iterations,
originalTime,
optimizedTime,
speedup: originalTime / optimizedTime,
originalStats: originalEngine.getStats(),
optimizedStats: optimizedEngine.getStats()
};
}
/**
* Generate comprehensive performance report
*/
async generateReport() {
console.log('๐ Performance Summary Report\n');
console.log('=' .repeat(60));
// Component improvements
console.log('\n๐ง Component-Level Improvements:');
console.log(` Lexer: ${this.results.lexer.speedup.toFixed(2)}x faster`);
console.log(` Scope Stack: ${this.results.scopes.speedup.toFixed(2)}x faster`);
console.log(` Built-ins: ${this.results.builtins.speedup.toFixed(2)}x faster`);
console.log(` AST Pool: ${this.results.astPool.speedup.toFixed(2)}x faster`);
// Program-level improvements
console.log('\n๐ Program-Level Improvements:');
let totalSpeedup = 0;
let programCount = 0;
for (const [name, result] of Object.entries(this.results.programs)) {
console.log(` ${name.padEnd(15)}: ${result.speedup.toFixed(2)}x faster`);
totalSpeedup += result.speedup;
programCount++;
}
const averageSpeedup = totalSpeedup / programCount;
console.log(` Average: ${averageSpeedup.toFixed(2)}x faster`);
// Memory and efficiency improvements
console.log('\n๐พ Memory & Efficiency:');
const astStats = this.results.astPool.stats;
console.log(` AST Pool Hit Rate: ${(astStats.hitRate * 100).toFixed(1)}%`);
console.log(` Object Reuse Rate: ${(astStats.reuseRate * 100).toFixed(1)}%`);
console.log(` Total Objects Pooled: ${astStats.totalPooledObjects}`);
const scopeStats = this.results.scopes.stats;
console.log(` Scope Hit Rate: ${(scopeStats.hitRate * 100).toFixed(1)}%`);
console.log(` Variable Slots: ${scopeStats.totalSlots}`);
// Recommendations
console.log('\n๐ก Optimization Impact Summary:');
console.log(` ๐ฏ Best improvement: ${this.getBestImprovement()}`);
console.log(` ๐ Overall speedup: ${averageSpeedup.toFixed(2)}x`);
console.log(` ๐ Memory efficiency: ${this.getMemoryEfficiency()}`);
console.log('\n' + '=' .repeat(60));
}
/**
* Identify the best performing optimization
*/
getBestImprovement() {
const improvements = {
'Lexer': this.results.lexer.speedup,
'Scope Stack': this.results.scopes.speedup,
'Built-ins': this.results.builtins.speedup,
'AST Pool': this.results.astPool.speedup
};
let best = { name: '', speedup: 0 };
for (const [name, speedup] of Object.entries(improvements)) {
if (speedup > best.speedup) {
best = { name, speedup };
}
}
return `${best.name} (${best.speedup.toFixed(2)}x)`;
}
/**
* Calculate overall memory efficiency improvement
*/
getMemoryEfficiency() {
const astHitRate = this.results.astPool.stats.hitRate;
const scopeHitRate = this.results.scopes.stats.hitRate;
const avgHitRate = (astHitRate + scopeHitRate) / 2;
if (avgHitRate > 0.8) return 'Excellent';
if (avgHitRate > 0.6) return 'Good';
if (avgHitRate > 0.4) return 'Fair';
return 'Needs improvement';
}
/**
* Save results to file
*/
async saveResults(filename = 'benchmark-results.json') {
const fs = await import('fs');
const resultsWithMetadata = {
timestamp: new Date().toISOString(),
nodeVersion: process.version,
platform: process.platform,
arch: process.arch,
...this.results
};
fs.writeFileSync(filename, JSON.stringify(resultsWithMetadata, null, 2));
console.log(`\n๐พ Results saved to ${filename}`);
}
}
/**
* Quick benchmark function for CLI usage
*/
export async function quickBenchmark() {
const suite = new BenchmarkSuite();
return await suite.runAll();
}
/**
* Memory usage benchmark
*/
export async function benchmarkMemoryUsage() {
console.log('๐ง Memory Usage Benchmark\n');
const testCode = `
range : n -> with rec (
helper : i acc ->
when i is
0 then acc
_ then helper (i - 1) (prepend i acc);
) -> helper n [];
numbers : range 1000;
doubled : map (x -> x * 2) numbers;
filtered : filter (x -> x > 100) doubled;
result : reduce (acc x -> acc + x) 0 filtered;
`;
// Measure memory before
const memBefore = process.memoryUsage();
// Run multiple iterations
const engine = new BabaYagaEngine();
for (let i = 0; i < 100; i++) {
await engine.execute(testCode);
}
// Force garbage collection if available
if (global.gc) {
global.gc();
}
// Measure memory after
const memAfter = process.memoryUsage();
console.log('Memory Usage:');
console.log(` Heap Used: ${((memAfter.heapUsed - memBefore.heapUsed) / 1024 / 1024).toFixed(2)} MB`);
console.log(` Heap Total: ${((memAfter.heapTotal - memBefore.heapTotal) / 1024 / 1024).toFixed(2)} MB`);
console.log(` External: ${((memAfter.external - memBefore.external) / 1024 / 1024).toFixed(2)} MB`);
return {
heapUsedDiff: memAfter.heapUsed - memBefore.heapUsed,
heapTotalDiff: memAfter.heapTotal - memBefore.heapTotal,
externalDiff: memAfter.external - memBefore.external
};
}
|