From ee695e935dfd31c6678ce4e9f2f472a33138530e Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 27 Aug 2013 17:28:27 -0700 Subject: [PATCH] child_process: Avoid extra copy for string stdio There's no need to create a new Buffer instance if we're just going to immediately call toString() at the end anyway. Better to create a string up front, and setEncoding() on the streams, and do a string concatenation instead. --- lib/child_process.js | 46 +++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/lib/child_process.js b/lib/child_process.js index 9c63154619..33928a945c 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -611,8 +611,18 @@ exports.execFile = function(file /* args, options, callback */) { windowsVerbatimArguments: !!options.windowsVerbatimArguments }); - var _stdout = []; - var _stderr = []; + var encoding; + var _stdout; + var _stderr; + if (options.encoding !== 'buffer' && Buffer.isEncoding(options.encoding)) { + encoding = options.encoding; + _stdout = ''; + _stderr = ''; + } else { + _stdout = []; + _stderr = []; + encoding = null; + } var stdoutLen = 0; var stderrLen = 0; var killed = false; @@ -633,13 +643,14 @@ exports.execFile = function(file /* args, options, callback */) { if (!callback) return; // merge chunks - var stdout = Buffer.concat(_stdout); - var stderr = Buffer.concat(_stderr); - - if (Buffer.isEncoding(options.encoding)) { - // convert to strings - stdout = stdout.toString(options.encoding); - stderr = stderr.toString(options.encoding); + var stdout; + var stderr; + if (!encoding) { + stdout = Buffer.concat(_stdout); + stderr = Buffer.concat(_stderr); + } else { + stdout = _stdout; + stderr = _stderr; } if (ex) { @@ -683,25 +694,38 @@ exports.execFile = function(file /* args, options, callback */) { } child.stdout.addListener('data', function(chunk) { - _stdout.push(chunk); stdoutLen += chunk.length; if (stdoutLen > options.maxBuffer) { ex = new Error('stdout maxBuffer exceeded.'); kill(); + } else { + if (!encoding) + _stdout.push(chunk); + else + _stdout += chunk; } }); child.stderr.addListener('data', function(chunk) { - _stderr.push(chunk); stderrLen += chunk.length; if (stderrLen > options.maxBuffer) { ex = new Error('stderr maxBuffer exceeded.'); kill(); + } else { + if (!encoding) + _stderr.push(chunk); + else + _stderr += chunk; } }); + if (encoding) { + child.stderr.setEncoding(encoding); + child.stdout.setEncoding(encoding); + } + child.addListener('close', exithandler); child.addListener('error', errorhandler);