在JavaScript中,我有一个循环,有许多迭代,并且在每次迭代中,我创建了一个包含许多+=
运算符的大字符串。有没有更有效的方法来创建一个字符串?我正在考虑创建一个动态数组,我不断添加字符串,然后进行连接。任何人都可以解释并举例说明最快的方法吗?
答案 0 :(得分:119)
基于JSPerf的基准测试似乎使用+=
是最快的方法,但不一定在每个浏览器中。
为了在DOM中构建字符串,它seems to be better首先连接字符串然后添加到DOM,而不是迭代地将它添加到dom中。你应该对自己的情况进行基准测试。
(感谢@zAlbee进行更正)
答案 1 :(得分:63)
我对连接本身没有评论,但我想指出@Jakub Hampl的建议:
为了在DOM中构建字符串,在某些情况下,迭代添加到DOM可能更好,而不是一次添加一个巨大的字符串。
是错误的,因为它是基于有缺陷的测试。该测试从未实际附加到DOM中。
这个fixed test表明在渲染之前一次创建字符串的速度要快得多。它甚至不是一场比赛。
(对不起,这是一个单独的答案,但我还没有足够的代表对答案发表评论。)
答案 2 :(得分:13)
自这个问题得到回答三年以后,无论如何我都会提供答案:)
实际上,接受的答案并不完全正确。 Jakub的测试使用硬编码字符串,允许JS引擎优化代码执行(谷歌的V8在这方面非常好!)。 但是只要你使用完全随机的字符串(here is JSPerf),字符串连接就会在第二位。
答案 3 :(得分:3)
您也可以使用template literals进行字符串连接。我更新了其他张贴者的JSPerf tests,将其包括在内。
for (var res = '', i = 0; i < data.length; i++) {
res = `${res}${data[i]}`;
}
答案 4 :(得分:1)
我对node和chrome都进行了快速测试,发现在两种情况下+=
都更快。惊奇地比节点上的模板文字快10倍:
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
来自Chrome 86.0.4240.198的结果:
答案 5 :(得分:0)
我想知道为什么String.prototype.concat
没有得到任何爱。在我的测试中(假设您已经有一个字符串数组),它的性能优于所有其他方法。
测试代码:
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)
答案 6 :(得分:0)
我无法评论其他人的答案(没有足够的代表),所以我会说 MadBreaks' answer 使用模板文字是好的,但如果构建需要与 IE 兼容的站点,则应小心(Internet Explorer),因为 template literals aren't compatible with IE。因此,在这种情况下,您可以只使用赋值运算符(+、+=)。