From 1b0e5b3ed11af961ce323ddb2df26b20c955b078 Mon Sep 17 00:00:00 2001 From: kpdecker Date: Wed, 24 Jun 2015 22:42:13 -0500 Subject: [PATCH] Avoid deopt in iterable destructure template The try/catch was forcing deoptimization under most engines. This roughly doubles throughput under V8 and 7x increases were seen under Firefox. Performance numbers based on https://github.com/kpdecker/six-speed/tree/master/tests/destructuring --- .../templates/helper-sliced-to-array.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/babel/transformation/templates/helper-sliced-to-array.js b/src/babel/transformation/templates/helper-sliced-to-array.js index 1285e55662..9659ca4cef 100644 --- a/src/babel/transformation/templates/helper-sliced-to-array.js +++ b/src/babel/transformation/templates/helper-sliced-to-array.js @@ -1,7 +1,7 @@ (function (arr, i) { - if (Array.isArray(arr)) { - return arr; - } else if (Symbol.iterator in Object(arr)) { + // Broken out into a separate function to avoid deoptimizations due to the try/catch for the + // array iterator case. + function sliceIterator() { // this is an expanded form of `for...of` that properly supports abrupt completions of // iterators etc. variable names have been minimised to reduce the size of this massive // helper. sometimes spec compliancy is annoying :( @@ -32,6 +32,12 @@ } } return _arr; + } + + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }