Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
10 kB ยท 335 lines
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336// Performance benchmark comparing old vs new architecture// Measures network call redundancies and timing improvements
import { KidLispCacheManager } from './cache-manager-prototype.mjs';import { KidLispInstanceManager } from './instance-manager-prototype.mjs';import { mockStore } from './mock-network.mjs';
async function runPerformanceBenchmark() { console.log('โก KidLisp V2 Performance Benchmark\n'); // Test scenarios const scenarios = [ { name: '$cow (2 embedded pieces)', mainCode: 'cow', expectedEmbedded: ['39i', 'r2f'] }, { name: 'Deep embedding (5 levels)', mainCode: 'deep-1', expectedEmbedded: ['deep-2', 'deep-3', 'deep-4', 'deep-5'] }, { name: 'Complex piece (simulated)', mainCode: 'cow', additionalFetches: ['39i', 'r2f', '39i', 'r2f'], // Simulate duplicate fetches expectedEmbedded: ['39i', 'r2f'] } ]; console.log('๐ฌ Running benchmark scenarios...\n'); for (const scenario of scenarios) { console.log(`๐ Scenario: ${scenario.name}`); // Test OLD architecture (simulated current behavior) const oldResults = await benchmarkOldArchitecture(scenario); // Test NEW architecture (proposed system) const newResults = await benchmarkNewArchitecture(scenario); // Calculate improvements const networkImprovement = ((oldResults.networkRequests - newResults.networkRequests) / oldResults.networkRequests * 100); const timeImprovement = ((oldResults.totalTime - newResults.totalTime) / oldResults.totalTime * 100); console.log(` ๐ Old architecture: ${oldResults.networkRequests} requests, ${oldResults.totalTime}ms`); console.log(` โก New architecture: ${newResults.networkRequests} requests, ${newResults.totalTime}ms`); console.log(` ๐ Network improvement: ${networkImprovement.toFixed(1)}%`); console.log(` โฑ๏ธ Time improvement: ${timeImprovement.toFixed(1)}%`); if (newResults.cyclesPrevented > 0) { console.log(` ๐ก๏ธ Cycles prevented: ${newResults.cyclesPrevented}`); } console.log(); } // Stress test console.log('๐งช Stress Test: Concurrent Requests'); await stressTestConcurrency(); // Memory usage test console.log('๐พ Memory Usage Test'); await testMemoryUsage();}
async function benchmarkOldArchitecture(scenario) { const startTime = Date.now(); // Clear state mockStore.clearRequestLog(); // Simulate current architecture behavior: // 1. Separate cache for disk API // 2. No deduplication // 3. Individual requests for each embedded piece // 4. Redundant fetches in different contexts const diskCache = new Map(); // Separate singleton cache const mainCache = new Map(); // Main KidLisp cache // 1. Main piece fetch let mainCode = await mockStore.fetchCode(scenario.mainCode); mainCache.set(scenario.mainCode, mainCode); // 2. Extract embedded codes (simulate parser) const embeddedCodes = scenario.expectedEmbedded || []; // 3. Fetch each embedded code separately (current behavior) for (const code of embeddedCodes) { // Simulate preload phase if (!mainCache.has(code)) { const fetchedCode = await mockStore.fetchCode(code); mainCache.set(code, fetchedCode); } // Simulate render phase (separate fetch in current system) if (!diskCache.has(code)) { const fetchedCode = await mockStore.fetchCode(code); diskCache.set(code, fetchedCode); } } // 4. Simulate additional fetches from scenario if (scenario.additionalFetches) { for (const code of scenario.additionalFetches) { await mockStore.fetchCode(code); // No cache check (redundant fetches) } } const endTime = Date.now(); const stats = mockStore.getRequestStats(); return { networkRequests: stats.total, duplicates: stats.duplicates.length, totalTime: endTime - startTime, cacheEfficiency: 0 // Old system has poor cache sharing };}
async function benchmarkNewArchitecture(scenario) { const startTime = Date.now(); // Clear state mockStore.clearRequestLog(); // Set up new architecture const cacheManager = new KidLispCacheManager(); const instanceManager = new KidLispInstanceManager(cacheManager); // 1. Create root instance const rootInstance = instanceManager.createInstance({ type: 'main-piece', cacheId: scenario.mainCode }); // 2. Fetch main code const mainCode = await cacheManager.getCachedCode(scenario.mainCode); // 3. Extract and batch fetch embedded codes const embeddedCodes = cacheManager.extractDollarCodes(mainCode); if (embeddedCodes.length > 0) { await cacheManager.getBatchCachedCodes(embeddedCodes); } // 4. Execute with recursion protection let cyclesPrevented = 0; try { const result = await instanceManager.executeWithRecursionGuard( rootInstance.id, mainCode, {} ); if (result.type === 'cycle-error' || result.type === 'depth-error') { cyclesPrevented++; } } catch (error) { // Handle any execution errors } // 5. Simulate additional fetches (should hit cache) if (scenario.additionalFetches) { for (const code of scenario.additionalFetches) { await cacheManager.getCachedCode(code); // Will hit cache } } const endTime = Date.now(); const stats = mockStore.getRequestStats(); const efficiency = cacheManager.getCacheEfficiency(); return { networkRequests: stats.total, duplicates: stats.duplicates.length, totalTime: endTime - startTime, cacheEfficiency: efficiency.hitRate, cyclesPrevented };}
async function stressTestConcurrency() { const cacheManager = new KidLispCacheManager(); mockStore.clearRequestLog(); const startTime = Date.now(); // Make 50 concurrent requests for the same codes const promises = []; for (let i = 0; i < 50; i++) { promises.push(cacheManager.getCachedCode('cow')); promises.push(cacheManager.getCachedCode('39i')); promises.push(cacheManager.getCachedCode('r2f')); } const results = await Promise.all(promises); const endTime = Date.now(); const stats = mockStore.getRequestStats(); const efficiency = cacheManager.getCacheEfficiency(); console.log(` ๐ข Made 150 concurrent requests`); console.log(` ๐ก Network requests: ${stats.total} (should be โค 3)`); console.log(` ๐ฏ Cache hit rate: ${efficiency.hitRate.toFixed(1)}%`); console.log(` โฑ๏ธ Total time: ${endTime - startTime}ms`); console.log(` ๐ Deduplication savings: ${efficiency.deduplicatedRequests} requests`); console.log();}
async function testMemoryUsage() { const cacheManager = new KidLispCacheManager(); const instanceManager = new KidLispInstanceManager(cacheManager); // Create many instances const instances = []; for (let i = 0; i < 100; i++) { const instance = instanceManager.createInstance({ type: 'test-instance', cacheId: `test-${i % 10}` // Reuse some cache IDs }); instances.push(instance); } const beforeGC = instanceManager.getStats(); console.log(` ๐๏ธ Created instances: ${beforeGC.totalInstances}`); // Age all instances for (const instance of instanceManager.instances.values()) { instance.lastUsed = Date.now() - 70000; // 70 seconds ago } // Run garbage collection const gcCount = instanceManager.garbageCollect(60000); const afterGC = instanceManager.getStats(); console.log(` ๐๏ธ Garbage collected: ${gcCount} instances`); console.log(` ๐พ Remaining instances: ${afterGC.totalInstances}`); console.log(` ๐ Cache entries: ${cacheManager.globalCache.size}`); console.log();}
// Recursion benchmarkasync function benchmarkRecursionDetection() { console.log('๐ Recursion Detection Benchmark'); const cacheManager = new KidLispCacheManager(); const instanceManager = new KidLispInstanceManager(cacheManager); const scenarios = [ { name: 'Simple cycle (A โ A)', code: '$recursive-a', expectCycle: true }, { name: 'Two-step cycle (A โ B โ A)', code: '$recursive-a', expectCycle: true }, { name: 'Deep recursion (5 levels)', code: '$deep-1', expectCycle: false } ]; for (const scenario of scenarios) { console.log(` ๐ Testing: ${scenario.name}`); instanceManager.clearAllInstances(); const rootInstance = instanceManager.createInstance({ type: 'main-piece', cacheId: scenario.code.substring(1) // Remove $ }); const startTime = Date.now(); let result; if (scenario.code === '$recursive-a') { // For recursive scenarios, manually set up the stack to force detection instanceManager.recursionStack = ['recursive-a']; result = await instanceManager.executeWithRecursionGuard( rootInstance.id, '(paint ($recursive-a 0 0 50 50))', // A calling itself {} ); } else { result = await instanceManager.executeWithRecursionGuard( rootInstance.id, `(paint (${scenario.code} 0 0 100 100))`, {} ); } const endTime = Date.now(); const isCycle = result.type === 'cycle-error'; const isDepthError = result.type === 'depth-error'; console.log(` โฑ๏ธ Detection time: ${endTime - startTime}ms`); console.log(` ๐ฏ Result: ${result.type}`); if (scenario.expectCycle && isCycle) { console.log(` โ
Correctly detected cycle`); } else if (!scenario.expectCycle && result.type === 'execution-result') { console.log(` โ
Correctly executed without cycle`); } else { console.log(` โ Unexpected result (expected cycle: ${scenario.expectCycle}, got: ${result.type})`); } } console.log();}
// Run benchmark if called directlyif (import.meta.url === `file://${process.argv[1]}`) { runPerformanceBenchmark() .then(() => benchmarkRecursionDetection()) .then(() => { console.log('๐ Benchmark complete!'); }) .catch(error => { console.error('โ Benchmark failed:', error); process.exit(1); });}
export { runPerformanceBenchmark, benchmarkRecursionDetection, benchmarkOldArchitecture, benchmarkNewArchitecture};