在 JavaScript 中连接字符串的最有效方法?

IT技术 javascript string performance concatenation
2021-01-12 14:29:47

在 JavaScript 中,我有一个包含多次迭代的循环,在每次迭代中,我都会创建一个包含许多+=运算符的巨大字符串有没有更有效的方法来创建字符串?我正在考虑创建一个动态数组,在其中不断向其中添加字符串,然后进行连接。任何人都可以解释并举例说明最快的方法吗?

6个回答

似乎基于JSPerf 的基准测试,使用+=是最快的方法,尽管不一定在每个浏览器中。

对于在 DOM 中构建字符串,似乎最好先连接字符串然后添加到 DOM,而不是迭代地将其添加到 dom。不过,您应该对自己的案例进行基准测试。

(感谢@zAlbee 的更正)

查看链接的页面。似乎+=在数组上执行连接和执行连接之间几乎没有区别
2021-03-20 14:29:47
链接页面在两个测试中都使用 +=,看不到 .join(),所以这是一个毫无意义的测试,只将噪音显示为任何“差异”。很好的例子说明了 js 的嘈杂程度……dom 比 string 慢,因此请谨慎使用它。
2021-03-28 14:29:47
时间只是一个组成部分。对于迭代例程,我想知道各种方法之间对GC的影响是什么?
2021-03-28 14:29:47
JSPerf 链接已失效
2021-04-05 14:29:47
似乎为每个字符串将它添加到 DOM 中66%(对于 IE9)比创建一个字符串然后将字符串添加到 DOM 更快。
2021-04-06 14:29:47

我对串联本身没有评论,但我想指出@Jakub Hampl 的建议:

对于在 DOM 中构建字符串,在某些情况下,迭代添加到 DOM 可能更好,而不是一次添加一个巨大的字符串。

是错误的,因为它基于有缺陷的测试。该测试实际上从未附加到 DOM 中。

这个固定的测试表明,在渲染之前一次性创建所有字符串要快得多。这甚至不是比赛。

(对不起,这是一个单独的答案,但我还没有足够的代表来评论答案。)

我认为它本身就值得一个答案,因为它包含一个测试和一个结论(尽管测试基于/启发于另一个答案,这应该没问题),不需要抱歉。
2021-03-19 14:29:47

自从回答这个问题三年过去了,但无论如何我都会提供我的答案:)

实际上,接受的答案并不完全正确。Jakub 的测试使用了硬编码字符串,它允许 JS 引擎优化代码执行(Google 的 V8 在这方面真的很棒!)。但是一旦您使用完全随机的字符串(这里是 JSPerf),那么字符串连接将排在第二位。

有趣的是,在我的 Windows 机器上使用 Chrome 54 和 Firefox 45,concat 的速度是其他两个使用您的版本的速度的两倍多。IE 11 的所有三个都与其他两个浏览器中的 non-concat 一样慢。
2021-04-04 14:29:47
它因版本而异。我想,现在 Chrome 的 VM 可能包含一些针对这种情况的预优化。我在 Chrome v53 上再次测试,现在连接是最快的解决方案 :D 相同的硬件,但不同的 Chrome 版本给出了完全不同的结果。
2021-04-07 14:29:47

我在 node 和 chrome 中都做了一个快速测试,发现在这两种情况下+=都更快:

var profile = func => { 
    var start = new Date();
    for (var i = 0; i < 10000000; i++) func('test');
    console.log(new Date() - start);
}
profile(x => "testtesttesttesttest");
profile(x => `${x}${x}${x}${x}${x}`);
profile(x => x + x + x + x + x );
profile(x => { var s = x; s += x; s += x; s += x; s += x; return s; });
profile(x => [x, x, x, x, x].join(""));
profile(x => { var a = [x]; a.push(x); a.push(x); a.push(x); a.push(x); return a.join(""); });

结果节点:7.0.10

  • 作业:8
  • 模板文字:524
  • 加:382
  • 加等于:379
  • 数组连接:1476
  • 数组推送连接:1651

chrome 86.0.4240.198 的结果:

  • 作业:6
  • 模板文字:531
  • 加:406
  • 加等于:403
  • 数组连接:1552
  • 数组推送连接:1813

您还可以使用模板文字进行字符串连接我更新了其他海报的JSPerf 测试以包含它。

for (var res = '', i = 0; i < data.length; i++) {
  res = `${res}${data[i]}`;
}
jsperf.com - "503: SERVICE_UNAVAILABLE"
2021-03-19 14:29:47