日期:2014-05-16  浏览次数:20397 次

JavaScript字符串连接的性能问题
在Professional JavaScript for Web Developers(第二版)一书中,看到一个关于字符串操作的例子,原文大意如下:
var str = "hello ";
str += "world";

这段代码的实际执行有以下六步:
1. Create a string to store "hello ".
2. Create a string to store "world".
3. Create a string to store the result of concatenation.
4. Copy the current contents of str into the result.
5. Copy the "world" into the result.
6. Update str to point to the result.
第2到6步在每次字符串拼接的时候都发生,使这个操作很费时。当该操作进行成千上万次时,性能上会有问题。解决的办法是使用Array来存储string并使用join()方法来创建最后的string.可用以下代码替代:
var arr = new Array;
arr[0] = "hello ";
arr[1] = "world";
var str = arr.join("");

使用上面的方法,无论有多少string,连接操作只发生一次:
1. Create a string to store the result.
2. Copy each string into the appropriate spot in the result.
但实际效果并非如此,可写一段测试代码:
function StringBuffer() {
this.__strings__ = new Array;
}
StringBuffer.prototype.append = function (str) {
this.__strings__.push(str);
};
StringBuffer.prototype.toString = function () {
return this.__strings__.join("");
};
var d1 = new Date();
var str = "";
for (var i=0; i < 10000000; i++) {
str += "text";
}
var d2 = new Date();
document.write("Concatenation with plus: " + (d2.getTime() - d1.getTime()) + "milliseconds");
var oBuffer = new StringBuffer();
d1 = new Date();
for (var i=0; i < 10000000; i++) {
oBuffer.append("text");
}
var sResult = oBuffer.toString();
d2 = new Date();
document.write("<br />Concatenation with StringBuffer: " + (d2.getTime() -
d1.getTime()) + " milliseconds");

最后,作者说,实际的情况是,使用“+”操作符,要比使用数组的方法节省100-200%的性能。
================================================================================
上面都是在这本书中写到的,我实际测试了下,在不同浏览器下有差异。
IE 9:
Concatenation with plus: 3036milliseconds
Concatenation with StringBuffer: 1210 milliseconds


Firefox 11.0
Concatenation with plus: 269milliseconds
Concatenation with StringBuffer: 3245 milliseconds


Chrome 18.0.1025.152 m
Concatenation with plus: 3081milliseconds
Concatenation with StringBuffer: 3455 milliseconds


可以看到,在IE9下,使用数组的方式效率反而更高,只有使用“+”操作符的40%,在FF下,使用“+”操作符交通大大优于数组方式,在Chrome下,两种方式差不多。