184

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

4

7 回答 7

156

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

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

(感谢@zAlbee 更正)

于 2013-05-22T16:16:38.607 回答
89

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

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

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

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

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

于 2013-12-15T05:55:22.120 回答
17

自从这个问题得到回答以来已经三年了,但无论如何我都会提供我的答案:)

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

于 2016-03-09T17:32:48.290 回答
14

我在 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
于 2020-11-19T18:40:16.227 回答
8

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

for (var res = '', i = 0; i < data.length; i++) {
  res = `${res}${data[i]}`;
}
于 2018-12-07T23:56:50.573 回答
4

我想知道为什么String.prototype.concat没有得到任何爱。在我的测试中(假设您已经有一个字符串数组),它优于所有其他方法。

perf.link 测试

测试代码:

const numStrings = 100;
const strings = [...new Array(numStrings)].map(() => Math.random().toString(36).substring(6));

const concatReduce = (strs) => strs.reduce((a, b) => a + b);

const concatLoop = (strs) => {
  let result = ''
  for (let i = 0; i < strings.length; i++) {
    result += strings[i];
  }
  return result;
}

// Case 1: 52,570 ops/s
concatLoop(strings);

// Case 2: 96,450 ops/s
concatReduce(strings)

// Case 3: 138,020 ops/s
strings.join('')

// Case 4: 169,520 ops/s
''.concat(...strings)
于 2020-11-28T09:18:33.763 回答
0

我无法评论其他人的答案(没有足够的代表),所以我会说MadBreaks使用模板文字的答案很好,但如果构建需要与 IE(Internet Explorer)兼容的网站,则应小心,因为模板文字与 IE 不兼容。因此,在这种情况下,您可以只使用赋值运算符(+、+=)。

于 2021-06-16T15:49:19.303 回答