-
Notifications
You must be signed in to change notification settings - Fork 581
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
774d751
commit cf2fb9d
Showing
21 changed files
with
354 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { spawn } from 'child_process'; | ||
import { createInterface } from 'readline'; | ||
|
||
async function runTest(scriptPath, label) { | ||
return new Promise((resolve, reject) => { | ||
const results = []; | ||
const process = spawn('node', ['--expose-gc', scriptPath]); | ||
const rl = createInterface({ input: process.stdout }); | ||
|
||
console.log(`开始运行${label}...`); | ||
|
||
rl.on('line', (line) => { | ||
// 只捕获性能相关的数据 | ||
if (line.includes('本轮耗时') || | ||
line.includes('平均每次') || | ||
line.includes('总计耗时') || | ||
line.includes('heapUsed')) { | ||
results.push(line.trim()); | ||
} | ||
}); | ||
|
||
process.stderr.on('data', (data) => { | ||
console.error(`${label} 错误: ${data}`); | ||
}); | ||
|
||
process.on('close', (code) => { | ||
resolve(results); | ||
}); | ||
|
||
process.on('error', (err) => { | ||
reject(err); | ||
}); | ||
}); | ||
} | ||
|
||
console.log('=== Compose 性能对比测试 ===\n'); | ||
|
||
function formatResults(original, newVer, diff) { | ||
// 格式化数值,左对齐 | ||
const format = (value, unit) => `${value.toFixed(2)}${unit}`.padEnd(10); | ||
|
||
const formatLine = (label, orig, origUnit, next, nextUnit, diffVal) => { | ||
const col1 = label.padEnd(20); // 第一列:标签 | ||
const col2 = `${format(orig, origUnit)} (旧)`.padEnd(20); // 第二列:旧值 | ||
const col3 = `${format(next, nextUnit)} (新)`.padEnd(20); // 第三列:新值 | ||
const col4 = `[提升: ${diffVal}%]`; // 第四列:提升 | ||
return `${col1}${col2}${col3}${col4}`; | ||
}; | ||
|
||
return [ | ||
formatLine('本轮耗时', original.roundTime, 'ms', newVer.roundTime, 'ms', diff.roundTime), | ||
formatLine('平均每次', original.avgTime, 'ms', newVer.avgTime, 'ms', diff.avgTime), | ||
formatLine('总计耗时', original.totalTime, 'ms', newVer.totalTime, 'ms', diff.totalTime), | ||
formatLine('堆内存', original.heapUsed, 'MB', newVer.heapUsed, 'MB', diff.heapUsed) | ||
].join('\n'); | ||
} | ||
|
||
try { | ||
const [originalResults, newResults] = await Promise.all([ | ||
runTest('./test-original.mjs', '原始版本'), | ||
runTest('./test-new.mjs', '新版本') | ||
]); | ||
|
||
console.log('\n=== 性能对比结果 ===\n'); | ||
|
||
const minLength = Math.min( | ||
originalResults.length - (originalResults.length % 4), | ||
newResults.length - (newResults.length % 4) | ||
); | ||
|
||
for (let i = 0; i < minLength; i += 4) { | ||
const checkpoint = (i / 4 + 1) * 10000; | ||
console.log(`\n检查点 ${checkpoint.toLocaleString()} 次:`); | ||
|
||
// 解析原始数据 | ||
const original = { | ||
roundTime: parseFloat(originalResults[i].match(/[\d.]+/)[0]), | ||
avgTime: parseFloat(originalResults[i + 1].match(/[\d.]+/)[0]), | ||
totalTime: parseFloat(originalResults[i + 2].match(/[\d.]+/)[0]), | ||
heapUsed: parseFloat(originalResults[i + 3].match(/[\d.]+/)[0]) | ||
}; | ||
|
||
// 解析新版本数据 | ||
const newVer = { | ||
roundTime: parseFloat(newResults[i].match(/[\d.]+/)[0]), | ||
avgTime: parseFloat(newResults[i + 1].match(/[\d.]+/)[0]), | ||
totalTime: parseFloat(newResults[i + 2].match(/[\d.]+/)[0]), | ||
heapUsed: parseFloat(newResults[i + 3].match(/[\d.]+/)[0]) | ||
}; | ||
|
||
// 计算性能差异 | ||
const diff = { | ||
roundTime: ((original.roundTime - newVer.roundTime) / original.roundTime * 100).toFixed(2), | ||
avgTime: ((original.avgTime - newVer.avgTime) / original.avgTime * 100).toFixed(2), | ||
totalTime: ((original.totalTime - newVer.totalTime) / original.totalTime * 100).toFixed(2), | ||
heapUsed: ((original.heapUsed - newVer.heapUsed) / original.heapUsed * 100).toFixed(2) | ||
}; | ||
|
||
console.log(formatResults(original, newVer, diff)); | ||
} | ||
|
||
} catch (error) { | ||
console.error('测试执行出错:', error); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// 测试重构版本 | ||
function dispatch(i, middlewareArr) { | ||
if (i === middlewareArr.length) return Promise.resolve(); | ||
const fn = middlewareArr[i]; | ||
return Promise.resolve( | ||
fn({}, () => dispatch(i + 1, middlewareArr)) | ||
); | ||
} | ||
|
||
function createNewCompose() { | ||
return (context, next) => { | ||
// 创建100个中间件 | ||
const newMiddlewareArr = Array(100).fill(null).map(() => | ||
async (ctx, next) => { | ||
await next(); | ||
} | ||
); | ||
|
||
return dispatch(0, newMiddlewareArr); | ||
}; | ||
} | ||
// 格式化内存数据 | ||
function formatMemory(bytes) { | ||
return (bytes / 1024 / 1024).toFixed(2) + ' MB'; | ||
} | ||
|
||
// 格式化内存使用情况 | ||
function formatMemoryUsage(memoryUsage) { | ||
return { | ||
heapUsed: formatMemory(memoryUsage.heapUsed), // 实际使用的堆内存 | ||
heapTotal: formatMemory(memoryUsage.heapTotal), // 总堆内存 | ||
rss: formatMemory(memoryUsage.rss), // 常驻集大小 | ||
external: formatMemory(memoryUsage.external) // V8 外部内存 | ||
}; | ||
} | ||
|
||
const compose = createNewCompose(); | ||
|
||
console.log('\n=== 重构版本测试 ==='); | ||
console.log('初始内存使用情况:'); | ||
console.table(formatMemoryUsage(process.memoryUsage())); | ||
|
||
let count = 0; | ||
const startTime = process.hrtime.bigint(); | ||
let lastTime = startTime; | ||
|
||
async function run() { | ||
while (count < 100000) { | ||
await compose({}); | ||
count++; | ||
|
||
if (count % 10000 === 0) { | ||
const currentTime = process.hrtime.bigint(); | ||
const totalTime = Number(currentTime - startTime) / 1e6; // 转换为毫秒 | ||
const intervalTime = Number(currentTime - lastTime) / 1e6; | ||
lastTime = currentTime; | ||
|
||
console.log(`\n执行 ${count.toLocaleString()} 次后的性能数据:`); | ||
console.log(`本轮耗时: ${intervalTime.toFixed(2)}ms`); | ||
console.log(`平均每次: ${(intervalTime / 10000).toFixed(3)}ms`); | ||
console.log(`总计耗时: ${totalTime.toFixed(2)}ms`); | ||
console.table(formatMemoryUsage(process.memoryUsage())); | ||
} | ||
} | ||
} | ||
|
||
run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// 测试原始版本 | ||
function createOriginalCompose() { | ||
return (context, next) => { | ||
// 创建100个中间件 | ||
const newMiddlewareArr = Array(100).fill(null).map(() => | ||
async (ctx, next) => { | ||
await next(); | ||
} | ||
); | ||
|
||
function dispatch(i) { | ||
if (i === newMiddlewareArr.length) return Promise.resolve(); | ||
const fn = newMiddlewareArr[i]; | ||
return Promise.resolve(fn({}, () => dispatch(i + 1))); | ||
} | ||
|
||
return dispatch(0); | ||
}; | ||
} | ||
// 格式化内存数据 | ||
function formatMemory(bytes) { | ||
return (bytes / 1024 / 1024).toFixed(2) + ' MB'; | ||
} | ||
|
||
// 格式化内存使用情况 | ||
function formatMemoryUsage(memoryUsage) { | ||
return { | ||
heapUsed: formatMemory(memoryUsage.heapUsed), | ||
heapTotal: formatMemory(memoryUsage.heapTotal), | ||
rss: formatMemory(memoryUsage.rss), | ||
external: formatMemory(memoryUsage.external) | ||
}; | ||
} | ||
|
||
const compose = createOriginalCompose(); | ||
|
||
console.log('\n=== 原始版本测试 ==='); | ||
console.log('初始内存使用情况:'); | ||
console.table(formatMemoryUsage(process.memoryUsage())); | ||
|
||
let count = 0; | ||
const startTime = process.hrtime.bigint(); | ||
let lastTime = startTime; | ||
|
||
async function run() { | ||
while (count < 100000) { | ||
await compose({}); | ||
count++; | ||
|
||
if (count % 10000 === 0) { | ||
const currentTime = process.hrtime.bigint(); | ||
const totalTime = Number(currentTime - startTime) / 1e6; // 转换为毫秒 | ||
const intervalTime = Number(currentTime - lastTime) / 1e6; | ||
lastTime = currentTime; | ||
|
||
console.log(`\n执行 ${count.toLocaleString()} 次后的性能数据:`); | ||
console.log(`本轮耗时: ${intervalTime.toFixed(2)}ms`); | ||
console.log(`平均每次: ${(intervalTime / 10000).toFixed(3)}ms`); | ||
console.log(`总计耗时: ${totalTime.toFixed(2)}ms`); | ||
console.table(formatMemoryUsage(process.memoryUsage())); | ||
} | ||
} | ||
} | ||
|
||
run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
node test-compare.mjs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,5 +47,5 @@ | |
"cacheDir": ".changelog" | ||
}, | ||
"npmClient": "npm", | ||
"version": "3.19.0" | ||
"version": "3.19.1" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.