JavaScript – 循环比逐行离散写入更快吗?

忽略所有代码清洁度和可读性,哪个脚本会更快完成?

这个:

for(var i = 0; i < 10; i++){
  --do that thing--
}

或这个:

--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--
--do that thing--

或者它们是相同的,性能方面的?

解决方法

通过反复“复制和粘贴”循环体来“展开”循环可以改善或降低性能.

结果取决于……

> …你的JavaScript引擎
> …循环体中的代码
> …你的代码记录得多好(不开玩笑!)

让我们使用Google流行的V8 JavaScript引擎(Chrome,Node)分析性能

普通循环:

var count = 0;
for (var i = 0; i < 10; i++) {
  count += 1;
}

展开循环:

var count = 0;
count += 1;
count += 1;
... 
count += 1;

结果:展开的循环速度提高了约10倍.

但是如果我们循环1000次而不是10次呢?然后展开的循环突然变得比普通循环慢10倍!

如果我们将简单的算术表达式与函数调用交换怎么办?

普通循环:

function f() {
  return 1;
}

var count = 0;
for (var i = 0; i < 10; i++) {
  count += f();
}

展开循环:

var count = 0;
count += f();
count += f();
... 
count += f();

结果:展开的循环速度提高了约50%.

但是如果我们在函数f中添加注释呢?

function f() {
  // bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
  return 1;
}

突然,展开的循环慢了约20%!

这是为什么?

>解析主体包含少于600个字符的函数时,V8会自动内联代码,包括空格和注释.
>当一个函数在很长的循环中“卡住”时,V8执行on-stack-replacement.

关于最后一个例子:通过添加长> 600个字符注释,我们阻止V8在解析过程中内联函数f并依赖于运行时优化功能(例如’on stack replacement’),它针对整个函数和循环而不是手动重复代码.

正如您所看到的,很难预测这种微观“优化”的结果.所以最好不要这样做 – 除非你针对特定JS引擎的特定版本.

有关性能分析,请参阅https://jsfiddle.net/Lj9v7c2m/ – 根据您的计算机/浏览器/版本,您可能会得到不同的结果.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...