JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增迭代器更快

2023-11-25

在他的书中更快的网站Steve Sounders 写道,提高循环性能的一个简单方法是将迭代器向 0 递减,而不是向总长度递增(实际上这一章是由 Nicholas C. Zakas 撰写的)。此更改可以使原始执行时间节省高达 50%,具体取决于每次迭代的复杂性。例如:

var values = [1,2,3,4,5];
var length = values.length;

for (var i=length; i--;) {
   process(values[i]);
}

这几乎与for循环,do-while循环,以及while loop.

我想知道,这是什么原因呢?为什么迭代器递减速度这么快?(我对此的技术背景感兴趣,而不是证明这一说法的基准。)


编辑:乍一看,这里使用的循环语法看起来是错误的。没有length-1 or i>=0,所以让我们澄清一下(我也很困惑)。

以下是一般的 for 循环语法:

for ([initial-expression]; [condition]; [final-expression])
   statement
  • 初始表达式 - var i=length

    首先评估该变量声明。

  • 状况 - i--

    在每次循环迭代之前都会计算该表达式。它将在第一次通过循环之前递减变量。如果该表达式的计算结果为false循环结束。在 JavaScript 中是0 == false so if i最终等于0它被解释为false循环结束。

  • 最终表达

    该表达式在每次循环迭代结束时计算(在下一次计算之前)状况)。这里不需要它并且是空的。所有三个表达式在 for 循环中都是可选的。

for 循环语法不是问题的一部分,但因为它有点不常见,我认为澄清它很有趣。也许它更快的原因之一是,因为它使用更少的表达式(0 == false“诡计”)。


我不确定 Javascript,在现代编译器下这可能并不重要,但在“过去”这段代码:

for (i = 0; i < n; i++){
  .. body..
}

会产生

move register, 0
L1:
compare register, n
jump-if-greater-or-equal L2
-- body ..
increment register
jump L1
L2:

而向后计数代码

for (i = n; --i>=0;){
  .. body ..
}

会产生

move register, n
L1:
decrement-and-jump-if-negative register, L2
.. body ..
jump L1
L2:

所以在循环内部它只执行两个额外的指令而不是四个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增迭代器更快 的相关文章

随机推荐

  • 将所有源文件一次传递给编译器有什么好处吗?

    我读过 整个程序优化 wpo 和 链接时间代码生成 ltcg 我想知道如果我将所有源代码从 cli 一次性传递给编译器 如 g a cpp b cpp 是否会进行更多模块间分析 或者这只是启用这些标志之一 编译器之间对此有区别吗 例如 英特
  • 直接从Java执行JSP

    我需要执行一个JSP 但我需要直接从 Java 而不使用 Tomcat 或任何其他 servlet 容器 编译 JSP 也是一件好事 但不是必需的 我认为 org apache jasper 包可能很适合这样做 但我在网上找不到任何好的示例
  • 登录时在 Windows 7 中自动运行 bat 脚本

    我最近从已故的祖母那里购买了一台 Windows 7 笔记本电脑 我一直用它来做工作和其他事情 我决定使用 VirtualBox 创建一个虚拟机 现在我想在 Windows 7 主机 计算机上创建一个用户 以便当我登录到该用户时它会自动运行
  • Android:AutoCompleteTextView 在未输入文本时显示建议

    我在用AutoCompleteTextView 当用户单击它时 我想显示建议 即使它没有文本 但是setThreshold 0 工作原理与setThreshold 1 因此用户必须输入至少 1 个字符才能显示建议 This is 记录的行为
  • 检查实例是否属于某种类型

    用它来检查是否c是一个实例TForm c GetType Name CompareTo TForm 0 除了使用之外 是否还有更类型安全的方法来做到这一点string作为参数CompareTo 这里的不同答案有两种不同的含义 如果你想检查一
  • 尝试从 Django 中的 POST 解析 `request.body` [重复]

    这个问题在这里已经有答案了 由于某种原因 我无法弄清楚为什么 Django 不处理我的request body内容正确 正在发送中JSON格式 并查看Network开发工具中的选项卡将其显示为请求负载 creator creatorname
  • 如何在字符串中使用反斜杠 (\)?

    我尝试了很多方法来获得单反斜杠从一个executed 我的意思不是来自的输入html 我可以得到特殊字符作为制表符 新行和许多其他内容 然后将它们转义为 t or n or someother character 但当 a 时我无法得到一个
  • 如何判断 Chrome 扩展是由真实用户安装还是由我在开发过程中安装?

    我在 Chrome 扩展程序中使用 Analytics 我只想在真人 不是我正在使用它时 使用扩展时才执行分析代码 以下任何一项是否可行 哪一项是最好的 确定扩展是打包安装还是解包安装 我认为这是最好的 因为解压显然意味着它 正在开发中 并
  • 值限制:类型“bar”已被推断为具有泛型类型

    在下面的代码片段中 我不明白为什么我必须撰写f and g方式函数foo可以以及为什么它不能按功能方式工作bar尝试去做 let f a b a b let g a a b a a let gt f1 f2 fun a b gt let x
  • 在类型 ' 上找不到带有类型 'string' 参数的索引签名

    我正在开发我的第一个 firebase typescript 函数项目 我有以下代码片段 const files status src api status f js invite src api invite f js user src
  • 如何将java序列化对象写入和读取到文件中

    我将把多个对象写入一个文件 然后在代码的另一部分检索它们 我的代码没有错误 但无法正常工作 您能帮我找出我的代码有什么问题吗 我从不同的网站阅读了不同的代码 但没有一个对我有用 这是我将对象写入文件的代码 MyClassList 是一个数组
  • 按下按钮时播放声音 - android

    我有这个代码 package com tct soundTouch import android app Activity import android media MediaPlayer import android os Bundle
  • 在 openSUSE 上安装最新的 Python

    我使用 Zypper 包管理器在 openSUSE 系统 参见下面的版本 上安装了 Python 这为我提供了 Python 3 2 但某些包需要 Python 3 3 更新为zypper update python3保留在 Python
  • Loaddata 未正确处理时间戳和时区

    我正在使用 django 1 4 1 并启用了 mysql 和时区 我将数据转储到 yaml 修改了一些字段以创建一些测试数据 并尝试将其重新加载 但是 即使指定了 tz Django 仍不断抱怨天真的日期时间 具体来说 我的负载数据有 f
  • 按频率对 SQL 查询记录进行排序

    有什么方法可以根据某个值在列中出现的频率来对从 SQL 查询中选择的记录进行排序吗 例如 如果有 5 个列 value1 的记录 3 个列 value2 的记录 以及 2 个列 value3 的记录 有没有办法让结果先显示 value1 然
  • mysql 仅替换某些字段

    我有一个 mysql 表 CREATE TABLE gfs localidad varchar 20 fecha datetime pp float 8 4 NOT NULL default 0 0000 temp float 8 4 NO
  • 获取特定区域的节点列表?

    我正在开发一款横向游戏 我需要知道某个区域中有哪些节点来实现 视线 之类的功能 现在我正在尝试使用 enumerateBodyiesInRect 但它检测到的主体距离评估的矩形 20px 或更多 我无法弄清楚为什么它如此不精确 这就是我现在
  • 如何在 php 中获取远程域的 HTTP 状态代码?

    我想创建一个批处理脚本 遍历数据库中的 20 000 个链接 并清除所有 404 等 如何获取远程 URL 的 HTTP 状态代码 最好不要使用curl 因为我没有安装它 CURL 会是完美的 但由于你没有它 你将不得不开始使用套接字 该技
  • R 中复杂的非等值合并

    我正在尝试在两个表之间进行复杂的非等值连接 我受到了上次 userR 2016 中的演示的启发 https channel9 msdn com events useR international R User conference useR
  • JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增迭代器更快

    在他的书中更快的网站Steve Sounders 写道 提高循环性能的一个简单方法是将迭代器向 0 递减 而不是向总长度递增 实际上这一章是由 Nicholas C Zakas 撰写的 此更改可以使原始执行时间节省高达 50 具体取决于每次