#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); /** * 性能测试脚本 - 对比不同处理方法的性能 */ class PerformanceTest { constructor() { this.testDir = path.join(__dirname, 'test-files'); this.results = []; this.setupTestEnvironment(); } /** * 设置测试环境 */ setupTestEnvironment() { if (!fs.existsSync(this.testDir)) { fs.mkdirSync(this.testDir, { recursive: true }); } this.createTestFiles(); } /** * 创建测试文件 */ createTestFiles() { const testFiles = [ { name: 'small.js', content: ` function smallTest(){console.log("small test");const data={x:1,y:2};console.error("error");return data;} console.warn("warning"); class Test{constructor(){console.debug("debug");}} ` }, { name: 'medium.js', content: ` function mediumTest(){ console.log("medium test start"); const users = [ {id:1,name:"Alice",console:"test"}, {id:2,name:"Bob",age:25}, {id:3,name:"Charlie",active:true} ]; console.log("Processing users:", users.length); users.forEach(user => { console.info("Processing user:", user.name); user.processed = true; }); console.debug("Processing complete"); return users; } class DataProcessor { constructor(data) { console.log("DataProcessor initialized"); this.data = data; console.debug("Data:", data); } process() { console.info("Starting data processing"); console.time("processing"); const result = this.data.map(item => { console.debug("Processing item:", item); return item * 2; }); console.timeEnd("processing"); console.log("Result:", result); return result; } } console.warn("Module loaded"); ` }, { name: 'large.js', content: ` function largeScaleProcessing(){ console.log("Starting large scale processing"); const startTime = Date.now(); // 大量数据处理 const data = []; for(let i = 0; i < 1000; i++){ console.debug("Processing item", i); data.push({ id: i, value: Math.random() * 100, timestamp: Date.now() }); } console.log("Generated", data.length, "items"); // 复杂处理逻辑 const processedData = data.map((item, index) => { console.info("Processing item", index, "of", data.length); if(index % 100 === 0){ console.warn("Progress checkpoint:", index); } return { ...item, processed: true, calculated: item.value * 2, category: item.value > 50 ? "high" : "low" }; }); console.timeEnd("processing"); console.log("Processing complete in", Date.now() - startTime, "ms"); // 统计分析 const stats = { total: processedData.length, high: processedData.filter(item => item.category === "high").length, low: processedData.filter(item => item.category === "low").length }; console.log("Statistics:", stats); console.debug("Final data sample:", processedData.slice(0, 5)); return { data: processedData, stats }; } class AnalyticsEngine { constructor() { console.log("AnalyticsEngine constructor"); this.metrics = []; this.console = "property"; // 测试字符串中的console } track(event, data) { console.info("Tracking event:", event); const metric = { event, data, timestamp: Date.now() }; this.metrics.push(metric); console.debug("Metric recorded:", metric); } generateReport() { console.log("Generating report"); console.time("report-generation"); const report = { totalMetrics: this.metrics.length, events: [...new Set(this.metrics.map(m => m.event))], timeRange: { start: Math.min(...this.metrics.map(m => m.timestamp)), end: Math.max(...this.metrics.map(m => m.timestamp)) } }; console.timeEnd("report-generation"); console.info("Report generated:", report); return report; } } // 执行测试 console.warn("Large module loaded"); const engine = new AnalyticsEngine(); console.log("Analytics engine ready"); ` } ]; testFiles.forEach(file => { const filePath = path.join(this.testDir, file.name); if (!fs.existsSync(filePath)) { fs.writeFileSync(filePath, file.content); } }); } /** * 测试方法性能 */ async testMethod(methodName, processFunction) { console.log(`\n🧪 Testing ${methodName}...`); const files = fs.readdirSync(this.testDir).filter(f => f.endsWith('.js')); const startTime = Date.now(); const results = []; for (const file of files) { const filePath = path.join(this.testDir, file); const inputContent = fs.readFileSync(filePath, 'utf8'); const fileStartTime = Date.now(); try { const outputContent = await processFunction(inputContent); const fileEndTime = Date.now(); const fileTime = fileEndTime - fileStartTime; results.push({ file, success: true, inputSize: inputContent.length, outputSize: outputContent.length, reduction: inputContent.length - outputContent.length, time: fileTime }); console.log(` ✅ ${file}: ${inputContent.length}→${outputContent.length} chars (${fileTime}ms)`); } catch (error) { const fileEndTime = Date.now(); const fileTime = fileEndTime - fileStartTime; results.push({ file, success: false, error: error.message, time: fileTime }); console.log(` ❌ ${file}: ${error.message} (${fileTime}ms)`); } } const endTime = Date.now(); const totalTime = endTime - startTime; const successful = results.filter(r => r.success); const totalInputSize = successful.reduce((sum, r) => sum + r.inputSize, 0); const totalOutputSize = successful.reduce((sum, r) => sum + r.outputSize, 0); const totalReduction = totalInputSize - totalOutputSize; const summary = { method: methodName, totalTime, files: results.length, successful: successful.length, failed: results.length - successful.length, totalInputSize, totalOutputSize, totalReduction, avgTimePerFile: totalTime / results.length }; console.log(`📊 ${methodName} Summary:`); console.log(` Total time: ${totalTime}ms`); console.log(` Success rate: ${successful.length}/${results.length}`); console.log(` Size reduction: ${totalReduction} chars (${((totalReduction/totalInputSize)*100).toFixed(1)}%)`); console.log(` Avg time per file: ${summary.avgTimePerFile.toFixed(1)}ms`); this.results.push(summary); return summary; } /** * 正则表达式方法(快速但可能不准确) */ regexMethod(input) { return input.replace(/console\.(log|error|warn|info|debug|assert|trace|table|group|groupEnd|time|timeEnd)\s*\([^;]*?\);?\s*/g, ''); } /** * 状态机方法(中等速度,较准确) */ stateMachineMethod(input) { const STATES = { NORMAL: 0, IN_STRING: 1, IN_TEMPLATE_STRING: 2, IN_REGEX: 3, IN_COMMENT: 4 }; let state = STATES.NORMAL; let stringChar = ''; let result = ''; for (let i = 0; i < input.length; i++) { const char = input[i]; const nextChar = input[i + 1]; switch (state) { case STATES.NORMAL: if (char === '/' && nextChar === '/') { state = STATES.IN_COMMENT; i++; } else if (char === '/' && nextChar === '*') { state = STATES.IN_COMMENT; i++; } else if (char === '"' || char === "'") { state = STATES.IN_STRING; stringChar = char; result += char; } else if (char === '`') { state = STATES.IN_TEMPLATE_STRING; result += char; } else if (char === '/' && !result.match(/[a-zA-Z0-9_$]$/)) { state = STATES.IN_REGEX; result += char; } else { result += char; } break; case STATES.IN_STRING: result += char; if (char === stringChar) { state = STATES.NORMAL; } else if (char === '\\') { result += input[++i]; } break; case STATES.IN_TEMPLATE_STRING: result += char; if (char === '`') { state = STATES.NORMAL; } else if (char === '\\') { result += input[++i]; } break; case STATES.IN_REGEX: result += char; if (char === '/' && !input[i-1].match(/\\/)) { state = STATES.NORMAL; } break; case STATES.IN_COMMENT: if (char === '\n') { state = STATES.NORMAL; result += char; } else if (char === '*' && nextChar === '/') { state = STATES.NORMAL; i++; } break; } } // 移除console语句 return result.replace(/console\.(log|error|warn|info|debug|assert|trace|table|group|groupEnd|time|timeEnd)\s*\([^;]*?\);?\s*/g, ''); } /** * Ollama AI方法(慢但最准确) */ async ollamaMethod(input) { const { removeConsoleWithOllama } = require('./ollama-console-remover.js'); return await removeConsoleWithOllama(input); } /** * 运行所有性能测试 */ async runAllTests() { console.log('🚀 Performance Test Suite'); console.log('=========================='); // 测试正则表达式方法 await this.testMethod('Regex (Fast)', (input) => this.regexMethod(input)); // 测试状态机方法 await this.testMethod('State Machine (Medium)', (input) => this.stateMachineMethod(input)); // 测试Ollama方法(如果可用) try { const { checkOllamaHealth } = require('./optimized-processor.js'); const isOllamaAvailable = await checkOllamaHealth(); if (isOllamaAvailable) { await this.testMethod('Ollama AI (Accurate)', (input) => this.ollamaMethod(input)); } else { console.log('\n⚠️ Ollama not available, skipping AI method test'); console.log(' Make sure Ollama is running: ollama serve'); console.log(' And model is pulled: ollama pull deepseek-coder:6.7b'); } } catch (error) { console.log('\n❌ Could not test Ollama method:', error.message); } this.generateReport(); } /** * 生成性能报告 */ generateReport() { console.log('\n📈 Performance Comparison Report'); console.log('================================='); if (this.results.length === 0) { console.log('No results to compare'); return; } // 找出最快的和最准确的 const fastest = this.results.reduce((min, r) => r.totalTime < min.totalTime ? r : min); const mostEffective = this.results.reduce((max, r) => r.totalReduction > max.totalReduction ? r : max); console.log('\n🏆 Winners:'); console.log(` Fastest: ${fastest.method} (${fastest.totalTime}ms)`); console.log(` Most Effective: ${mostEffective.method} (${mostEffective.totalReduction} chars removed)`); console.log('\n📊 Detailed Comparison:'); console.log('Method | Time (ms) | Files | Reduction | Avg/File'); console.log('-----------------------|-----------|-------|-----------|----------'); this.results.forEach(result => { const method = result.method.padEnd(23); const time = result.totalTime.toString().padStart(9); const files = result.successful.toString().padStart(5); const reduction = result.totalReduction.toString().padStart(9); const avgFile = result.avgTimePerFile.toFixed(1).padStart(8); console.log(`${method} | ${time} | ${files} | ${reduction} | ${avgFile}`); }); // 保存报告 const reportData = { timestamp: new Date().toISOString(), results: this.results, summary: { fastest: fastest.method, mostEffective: mostEffective.method, totalTests: this.results.length } }; const reportPath = path.join(__dirname, 'performance-report.json'); fs.writeFileSync(reportPath, JSON.stringify(reportData, null, 2)); console.log(`\n💾 Detailed report saved to: ${reportPath}`); } } // 主程序 async function main() { const tester = new PerformanceTest(); try { await tester.runAllTests(); } catch (error) { console.error('❌ Performance test failed:', error.message); process.exit(1); } } if (require.main === module) { main().catch(console.error); } module.exports = PerformanceTest;