javascript-TypeScript Transpile-循环vs数组切片

前端之家收集整理的这篇文章主要介绍了javascript-TypeScript Transpile-循环vs数组切片 前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在ES6中,我们可以使用rest参数,有效地创建参数数组. TypeScript使用for循环将其转换为ES5.我想知道是否存在使用for循环方法比使用Array.prototype.slice更好的选择?也许存在slice选项无法涵盖的极端情况?

  1. // Written in TypeScript
  2. /*
  3. const namesJoinTS = function (firstName,...args) {
  4. return [firstName,...args].join(' ');
  5. }
  6. const res = namesJoinTS('Dave','B','Smith');
  7. console.log(res)
  8. */
  9. // TypeScript above transpiles to this:
  10. var namesJoinTS = function (firstName) {
  11. var args = [];
  12. for (var _i = 1; _i < arguments.length; _i++) {
  13. args[_i - 1] = arguments[_i];
  14. }
  15. return [firstName].concat(args).join(' ');
  16. };
  17. var res = namesJoinTS('Dave','Smith');
  18. console.log(res); //Dave B Smith
  19. // Vanilla JS
  20. var namesJoinJS = function (firstName) {
  21. var args = [].slice.call(arguments,1);
  22. return [firstName].concat(args).join(' ');
  23. };
  24. var res = namesJoinJS('Dave','Smith');
  25. console.log(res); // //Dave B Smith
最佳答案
这种怪异的转换是旧版V8曾经(可能仍然)有偏差优化的副作用.他们极大地优化了某些模式,但并不关心整体性能,因此,一些奇怪的模式(例如将参数复制到数组中的for循环*)的运行速度更快.因此,图书馆和图书馆的维护者.编译器开始寻找相应的方法来优化其代码,因为它们的代码可在数百万个设备上运行并且每毫秒计数.现在,随着V8中的优化变得更加成熟并专注于平均性能,这些技巧中的大多数不再起作用.将它们从代码库中重构出来只是时间问题.

此外,JavaScript正在朝着一种可以更轻松地优化的语言的方向发展,诸如参数之类的旧功能被更严格的新功能(剩余属性)所替代,从而具有更高的性能.使用它们通过美观的代码实现良好的性能,参数是过去的错误.

I was wondering is there any scenarios where using the for loop approach is a better option than using Array.prototype.slice?

好吧,在较早的V8版本上速度更快,但仍然需要测试这种情况.如果您为项目编写代码,我将始终选择更优雅的解决方案,在99%的情况下,理论上可能会松散的毫秒数无关紧要.

Maybe there are edge cases that the slice option does not cover?

否(AFAIK).

*您可能会问“为什么更快?”,那是因为:

参数本身很难优化,因为

1)可以重新分配(参数= 3)

2)它必须是“实时的”,不断变化的参数将反映到参数中

因此,只有直接访问它,才能对其进行优化,因为编译器随后可能会用变量引用替换类似数组的访问器:

  1. function slow(a) {
  2. console.log(arguments[0]);
  3. }
  4. // can be turned into this by the engine:
  5. function fast(a) {
  6. console.log(a);
  7. }

如果您内联循环并且如果参数数量更改,则回退到另一个版本(可能更慢),这也适用于循环:

  1. function slow() {
  2. for(let i = 0; i < arguments.length; i++) {
  3. console.log(arguments[i]);
  4. }
  5. }
  6. slow(1,2,3);
  7. slow(4,5,6);
  8. slow("what?");
  9. // can be optimized to:
  10. function fast(a,b,c) {
  11. console.log(a);
  12. console.log(b);
  13. console.log(c);
  14. }
  15. function fast2(a) {
  16. console.log(a);
  17. }
  18. fast(1,3);
  19. fast(4,6);
  20. fast2("what?");

现在,如果您调用另一个函数并传递参数,则情况将变得非常复杂:

  1. var leaking;
  2. function cantBeOptimized(a) {
  3. leak(arguments); // uurgh
  4. a = 1; // this has to be reflected to "leaking" ....
  5. }
  6. function leak(stuff) { leaking = stuff; }
  7. cantBeOptimized(0);
  8. console.log(leaking[0]); // has to be 1

这不能真正优化,这是性能问题.
因此,调用函数并传递参数在性能上是一个坏主意.

猜你在找的JavaScript相关文章