node.js在使用child_process之后会降低性能

运行subprocess(使用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。

此外,只有在昂贵的操作中运行string连接和math运算时才会出现此问题 – 如果两者都被注释掉,则不存在问题。

UPDATE

这实际上只发生在chid进程完成之后 – subprocess运行时没有效果,请参阅以下更新的代码示例并输出:

 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 

背景

我最初发现这个问题,因为我正在使用产卵调用ffmpeg解码一个MP3。 当audio样本正在返回时,我正在计算FFT。 我注意到,我第一次这样做(而ffmpeg仍然在输出audio样本)计算时间很好,但第二次(第一次产卵后),它是非常缓慢的。