TypeScript Version: 2.7.0-dev.20171110
When using the --downlevelIteration compiler option, a plain JS array for..of iteration is transpiled into very complex code.
Code
let arr = [1, 2, 3];
for (const value of arr) {
console.log(value);
}
Expected behavior:
Should emit:
"use strict";
var arr = [1, 2, 3];
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
var value = arr_1[_i];
console.log(value);
}
This above is emitted if --downlevelIteration is false.
Actual behavior:
With --downlevelIteration set to true, the following is emitted:
"use strict";
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
var arr = [1, 2, 3];
try {
for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
var value = arr_1_1.value;
console.log(value);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
}
finally { if (e_1) throw e_1.error; }
}
var e_1, _a;
This will be slower in hot code, but it also seems unnecessary if we know that this is a plain array.
We don't change the emitted code based on the types involved - see https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals non-goal number 5.
@RyanCavanaugh Is there a distinction between changing emitted code based on type for a feature vs. for optimization?
No
Closing since this issue has been indicated to be working as intended.
There is an interesting clash between non-goals 5 and 2, "Aggressively optimize the runtime performance of programs. Instead, emit idiomatic JavaScript code that plays well with the performance characteristics of runtime platforms." – where the here requested emitted code is very idiomatic (and also happens to be aggressively performant), and the currently emitted code is everything but either.
Unfortunately this decision has a huge performance impact in IE.
I have to choose between using ES5 output with fast array iteration or manually write this code in ES6 output and disallow for..of for arrays.
Please reconsider this.
Most helpful comment
Unfortunately this decision has a huge performance impact in IE.
I have to choose between using ES5 output with fast array iteration or manually write this code in ES6 output and disallow for..of for arrays.
Please reconsider this.