From e5463cc2a97cafbf9d35656038f19b45dd75ffce Mon Sep 17 00:00:00 2001 From: Lee Byron Date: Wed, 14 Jan 2015 18:49:23 -0500 Subject: [PATCH] Improve performance of rest parameter. Rather than initing an empty array and filling, create an array of the correct size up-front. Minor gain on chromium, but considerably (~5x) faster in spidermonkey/firefox. --- lib/6to5/transformation/templates/rest.js | 2 +- .../transformers/es6-rest-parameters.js | 20 +++++++++++++------ .../arrow-functions/expected.js | 6 +++--- .../es6-rest-parameters/multiple/expected.js | 12 +++++------ .../es6-rest-parameters/single/expected.js | 12 +++++------ 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/6to5/transformation/templates/rest.js b/lib/6to5/transformation/templates/rest.js index f396f01117..c15ce8815d 100644 --- a/lib/6to5/transformation/templates/rest.js +++ b/lib/6to5/transformation/templates/rest.js @@ -1,3 +1,3 @@ -for (var KEY = START; KEY < ARGUMENTS.length; KEY++) { +for (var LEN = ARGUMENTS.length, ARRAY = Array(ARRAY_LEN), KEY = START; KEY < LEN; KEY++) { ARRAY[ARRAY_KEY] = ARGUMENTS[KEY]; } diff --git a/lib/6to5/transformation/transformers/es6-rest-parameters.js b/lib/6to5/transformation/transformers/es6-rest-parameters.js index 266b6f62f7..d1de130e31 100644 --- a/lib/6to5/transformation/transformers/es6-rest-parameters.js +++ b/lib/6to5/transformation/transformers/es6-rest-parameters.js @@ -14,23 +14,31 @@ exports.Function = function (node, parent, file) { var start = t.literal(node.params.length); var key = file.generateUidIdentifier("key"); + var len = file.generateUidIdentifier("len"); var arrKey = key; if (node.params.length) { - arrKey = t.binaryExpression("-", arrKey, start); + arrKey = t.binaryExpression("-", key, start); + } + + var arrLen = len; + if (node.params.length) { + arrLen = t.conditionalExpression( + t.binaryExpression(">", len, start), + t.binaryExpression("-", len, start), + t.literal(0) + ); } node.body.body.unshift( - t.variableDeclaration("var", [ - t.variableDeclarator(rest, t.arrayExpression([])) - ]), - util.template("rest", { ARGUMENTS: argsId, ARRAY_KEY: arrKey, + ARRAY_LEN: arrLen, START: start, ARRAY: rest, - KEY: key + KEY: key, + LEN: len, }) ); }; diff --git a/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js b/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js index cb971ebc77..fa875fd363 100644 --- a/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js +++ b/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js @@ -1,9 +1,9 @@ "use strict"; var concat = function () { - var arrs = []; - - for (var _key = 0; _key < arguments.length; _key++) { + for (var _len = arguments.length, + arrs = Array(_len), + _key = 0; _key < _len; _key++) { arrs[_key] = arguments[_key]; } }; diff --git a/test/fixtures/transformation/es6-rest-parameters/multiple/expected.js b/test/fixtures/transformation/es6-rest-parameters/multiple/expected.js index 56ff1c407f..dc6e082ce6 100644 --- a/test/fixtures/transformation/es6-rest-parameters/multiple/expected.js +++ b/test/fixtures/transformation/es6-rest-parameters/multiple/expected.js @@ -1,17 +1,17 @@ "use strict"; var t = function (f) { - var items = []; - - for (var _key = 1; _key < arguments.length; _key++) { + for (var _len = arguments.length, + items = Array(_len > 1 ? _len - 1 : 0), + _key = 1; _key < _len; _key++) { items[_key - 1] = arguments[_key]; } }; function t(f) { - var items = []; - - for (var _key2 = 1; _key2 < arguments.length; _key2++) { + for (var _len2 = arguments.length, + items = Array(_len2 > 1 ? _len2 - 1 : 0), + _key2 = 1; _key2 < _len2; _key2++) { items[_key2 - 1] = arguments[_key2]; } } diff --git a/test/fixtures/transformation/es6-rest-parameters/single/expected.js b/test/fixtures/transformation/es6-rest-parameters/single/expected.js index 316b3ec9a4..d6f9e1a5fe 100644 --- a/test/fixtures/transformation/es6-rest-parameters/single/expected.js +++ b/test/fixtures/transformation/es6-rest-parameters/single/expected.js @@ -1,17 +1,17 @@ "use strict"; var t = function () { - var items = []; - - for (var _key = 0; _key < arguments.length; _key++) { + for (var _len = arguments.length, + items = Array(_len), + _key = 0; _key < _len; _key++) { items[_key] = arguments[_key]; } }; function t() { - var items = []; - - for (var _key2 = 0; _key2 < arguments.length; _key2++) { + for (var _len2 = arguments.length, + items = Array(_len2), + _key2 = 0; _key2 < _len2; _key2++) { items[_key2] = arguments[_key2]; } }