跳转到内容

JavaScript/优化

来自维基教科书,自由的教科书



TODO
待办事项

编辑注
以下仅为大纲,待完善。


JavaScript 优化

[编辑 | 编辑源代码]

优化技巧

[编辑 | 编辑源代码]
  • 高级优化
    • 算法优化(数学分析)
    • 简化
  • 低级优化
    • 循环展开
    • 强度削减
    • Duff's Device
    • 清理循环
  • 外部工具和库,用于加速/优化/压缩 JavaScript 代码

常见错误和误解

[编辑 | 编辑源代码]

字符串连接

[编辑 | 编辑源代码]

JavaScript 中的字符串是不可变对象。这意味着,一旦创建了字符串对象,要修改它,理论上必须创建一个新的字符串对象。

现在,假设您想对一个长字符串中的所有字符执行 ROT-13 操作。假设您有一个 rot13() 函数,那么完成此操作的明显方法可能是

var s1 = "the original string";
var s2 = "";

for (i = 0; i < s1.length; i++) {
  s2 += rot13(s1.charAt(i));
}

特别是在 Internet Explorer 6 等较旧的浏览器中,这将非常缓慢。这是因为,在每次迭代中,必须复制整个字符串,然后才能附加新字母。

一种使此脚本更快的办法可能是创建一个字符数组,然后将其连接起来

var s1 = "the original string";
var a2 = new Array(s1.length);
var s2 = "";

for (i = 0; i < s1.length; i++) {
  a2[i] = rot13(s1.charAt(i));
}
s2 = a2.join('');

Internet Explorer 6 将更快地运行此代码。但是,由于原始代码非常直观且易于编写,因此大多数现代浏览器都改进了对这种连接的处理。在某些浏览器上,原始代码可能比此代码更快。

提高此代码速度的第二种方法是将要写入的字符串分解。例如,如果这是普通文本,空格可能是一个很好的分隔符

var s1 = "the original string";
var c;
var st = "";
var s2 = "";

for (i = 0; i < s1.length; i++) {
  c = rot13(s1.charAt(i));
  st += c;
  if (c == " ") {
    s2 += st;
    st = "";
  }
}
s2 += st;

这样,新字符串的大部分被复制的频率要低得多,因为单个字符被添加到较小的临时字符串中。

在 for 循环中真正提高速度的第三种方法是将 [数组] .length 语句移到条件语句之外。事实上,每次出现时,[数组] .length 都会重新计算。对于两个出现次数的循环,结果将不可见,但(例如)在五千次出现次数的循环中,您将看到差异。可以用简单的计算来解释

// we assume that myArray.length is 5000
for (x = 0;x < myArray.length;x++){
// doing some stuff
}

"x = 0" 仅评估一次,因此仅为一次操作。

"x < myArray.length" 评估了 5000 次,因此为 10,000 次操作(myArray.length是操作,比较myArray.length与 x 相比,是另一项操作)。

"x++" 评估了 5000 次,因此为 5000 次操作。

总共有 15 001 次操作。

// we assume that myArray.length is 5000
for (x = 0, l = myArray.length; x < l; x++){
// doing some stuff
}

"x = 0" 仅评估一次,因此仅为一次操作。

"l = myArray.length" 仅评估一次,因此仅为一次操作。

"x < l" 评估了 5000 次,因此为 5000 次操作(l 与 x 相比,是一次操作)。

"x++" 评估了 5000 次,因此为 5000 次操作。

总共有 10002 次操作。

因此,为了优化您的 for 循环,您需要编写以下代码

var s1 = "the original string";
var c;
var st = "";
var s2 = "";

for (i = 0, l = s1.length; i < l; i++) {
  c = rot13(s1.charAt(i));
  st += c;
  if (c == " ") {
    s2 += st;
    st = "";
  }
}
s2 += st;
华夏公益教科书