San*_*Lee 108 javascript performance string-concatenation
今天,我读到了关于字符串连接速度的这个帖子.
令人惊讶的是,字符串连接是赢家:
结果与我的想法相反.此外,大约有这么多的文章,其解释相反像这样.
我可以猜测浏览器已针对concat最新版本的字符串进行了优化,但他们如何做到这一点?我们可以说+在连接字符串时使用它会更好吗?
更新
因此,在现代浏览器中,字符串连接已经过优化,因此使用+符号比使用连接字符串join时要快.
但@Arthur指出,join如果你真的想用分隔符连接字符串会更快.
Daa*_*aan 145
浏览器字符串优化已更改字符串连接图片.
Firefox是第一个优化字符串连接的浏览器.从版本1.0开始,阵列技术实际上比在所有情况下使用plus运算符慢.其他浏览器也优化了字符串连接,因此Safari,Opera,Chrome和Internet Explorer 8也使用plus运算符显示更好的性能.版本8之前的Internet Explorer没有这样的优化,因此阵列技术总是比plus运算符快.
V8 javascript引擎(在Google Chrome中使用)使用此代码进行字符串连接:
// ECMA-262, section 15.5.4.6
function StringConcat() {
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
throw MakeTypeError("called_on_null_or_undefined", ["String.prototype.concat"]);
}
var len = %_ArgumentsLength();
var this_as_string = TO_STRING_INLINE(this);
if (len === 1) {
return this_as_string + %_Arguments(0);
}
var parts = new InternalArray(len + 1);
parts[0] = this_as_string;
for (var i = 0; i < len; i++) {
var part = %_Arguments(i);
parts[i + 1] = TO_STRING_INLINE(part);
}
return %StringBuilderConcat(parts, len + 1, "");
}
Run Code Online (Sandbox Code Playgroud)
因此,在内部他们通过创建一个InternalArray(parts变量)来优化它,然后填充.使用这些部分调用StringBuilderConcat函数.它很快,因为StringBuilderConcat函数是一些经过大量优化的C++代码.这里引用的时间太长了,但是在runtime.cc文件中搜索RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat)以查看代码.
evi*_*pie 23
Firefox速度很快,因为它使用的是Ropes(Ropes:Strings的替代品).绳索基本上只是一个DAG,其中每个节点都是一个字符串.
例如,如果您愿意a = 'abc'.concat('def'),新创建的对象将如下所示.当然,这并不完全是在内存中的样子,因为你仍然需要有字符串类型,长度和其他字段.
a = {
nodeA: 'abc',
nodeB: 'def'
}
Run Code Online (Sandbox Code Playgroud)
和 b = a.concat('123')
b = {
nodeA: a, /* {
nodeA: 'abc',
nodeB: 'def'
} */
nodeB: '123'
}
Run Code Online (Sandbox Code Playgroud)
因此,在最简单的情况下,VM几乎不做任何工作.唯一的问题是这会减慢对结果字符串的其他操作.这当然也减少了内存开销.
另一方面['abc', 'def'].join(''),通常只需分配内存来在内存中布置新的字符串.(也许这应该优化)
小智 7
对于大量数据连接更快,因此问题陈述不正确。
let result = "";
let startTime = new Date().getTime();
for (let i = 0; i < 2000000; i++) {
result += "x";
}
console.log("concatenation time: " + (new Date().getTime() - startTime));
startTime = new Date().getTime();
let array = new Array(2000000);
for (let i = 0; i < 2000000; i++) {
array[i] = "x";
}
result = array.join("");
console.log("join time: " + (new Date().getTime() - startTime));Run Code Online (Sandbox Code Playgroud)
在 Chrome 72.0.3626.119、Firefox 65.0.1、Edge 42.17134.1.0 上测试。请注意,即使包含数组创建,它也更快!
我知道这是一个旧线程,但是您的测试不正确。您正在做的output += myarray[i];事情应该更像是output += "" + myarray[i];因为您忘记了,必须将物品与物品粘合在一起。concat代码应类似于:
var output = myarray[0];
for (var i = 1, len = myarray.length; i<len; i++){
output += "" + myarray[i];
}
Run Code Online (Sandbox Code Playgroud)
这样,由于将元素粘合在一起,您正在执行两项操作,而不是一项。
Array.join() 是比较快的。
| 归档时间: |
|
| 查看次数: |
88463 次 |
| 最近记录: |