运行子进程(使用exec或spawn)后,我发现node.js应用程序的性能下降了10倍。下面是一个人为的例子和输出。
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
function runExpensiveOperation(times) {
while(times > 0) {
console.time('expensiveOperation');
var str = 'lorem';
for ( var i=0;i< 10000000; i++) {
// string concatenation
str = str.length < 1000 ? str + str : '';
// math operation
i * i * i;
}
console.timeEnd('expensiveOperation');
times--;
}
}
console.log('PRE EXEC');
runExpensiveOperation(10);
exec('echo "hello"');
console.log('POST EXEC');
runExpensiveOperation(10);
输出:
PRE EXEC
expensiveOperation: 66.458ms
expensiveOperation: 65.735ms
expensiveOperation: 69.237ms
expensiveOperation: 65.269ms
expensiveOperation: 69.133ms
expensiveOperation: 65.639ms
expensiveOperation: 67.944ms
expensiveOperation: 63.595ms
expensiveOperation: 64.153ms
expensiveOperation: 65.093ms
POST EXEC
expensiveOperation: 715.861ms
expensiveOperation: 739.671ms
expensiveOperation: 714.546ms
expensiveOperation: 714.845ms
expensiveOperation: 745.719ms
expensiveOperation: 743.240ms
expensiveOperation: 716.481ms
expensiveOperation: 732.916ms
expensiveOperation: 736.576ms
expensiveOperation: 742.416ms
这段代码有什么问题吗?有没有人遇到过类似的东西,或者这可能是我个人机器的问题?我目前正在运行节点版本5.8.0。
此外,如果字符串连接AND数学运算在expensiveOperation中运行,则只会出现此问题 - 如果其中任何一个被注释掉,则没有问题。
更新
这实际上只发生在chid进程完成后 - 子进程运行时没有效果,请参阅以下更新的代码示例和输出:
console.log('PRE SPAWN');
runExpensiveOperation(10);
// simple endpoint that holds the http request for 3 seconds
var process = spawn('curl',['https://httpbin.org/delay/3']);
process.on('exit', function(){
console.log('SPAWN EXIT');
runExpensiveOperation(10);
});
setTimeout(function(){
console.log('POST SPAWN');
runExpensiveOperation(10);
},100);
输出:
PRE SPAWN
expensiveOperation: 68.140ms
expensiveOperation: 64.574ms
expensiveOperation: 65.773ms
expensiveOperation: 71.974ms
expensiveOperation: 63.766ms
expensiveOperation: 66.595ms
expensiveOperation: 71.057ms
expensiveOperation: 62.015ms
expensiveOperation: 76.570ms
expensiveOperation: 75.234ms
POST SPAWN
expensiveOperation: 75.726ms
expensiveOperation: 70.672ms
expensiveOperation: 66.938ms
expensiveOperation: 68.169ms
expensiveOperation: 73.752ms
expensiveOperation: 76.147ms
expensiveOperation: 68.912ms
expensiveOperation: 75.144ms
expensiveOperation: 74.116ms
expensiveOperation: 67.488ms
SPAWN EXIT
expensiveOperation: 782.959ms
expensiveOperation: 769.501ms
expensiveOperation: 771.076ms
expensiveOperation: 737.611ms
expensiveOperation: 708.857ms
expensiveOperation: 716.193ms
expensiveOperation: 704.008ms
expensiveOperation: 707.031ms
expensiveOperation: 701.662ms
expensiveOperation: 714.501ms
背景
我最初发现这个问题是因为我使用spawn来调用ffmpeg来解码mp3。当音频样本被返回时,我正在计算FFT。我注意到我第一次这样做(虽然ffmpeg仍然输出音频样本)计算时间很好,但第二次(在第一次产生完成后)它非常慢。