JavaScript字符串拼接性能优化:模拟Java StringBuffer机制

作者:性能诊所

时间:2026-10-28

浏览:95

本文探讨JavaScript中字符串不可变的特性及其对性能的影响,特别是在低版本IE浏览器中的表现。通过模拟Java的StringBuffer机制,利用数组push和join方法实现高效的字符串拼接,并提供测试代码对比不同循环次数下的执行耗时,为IE6等老旧环境提供优化建议。

文章目录

JavaScript字符串不可变性与性能瓶颈

在研读《JavaScript高级程序设计》时,书中指出ECMAScript里的字符串具有不可变性。这意味着一旦字符串被创建,其内容便无法更改。若要修改变量中存储的字符串,系统必须先销毁原有字符串,再创建一个包含新值的新字符串并赋值给该变量。例如:

代码如下:

var lang = "Java";
lang = lang + "Script";

上述操作的底层过程是:系统首先创建一个能容纳10个字符的新字符串,将“Java”和“Script”填充其中,最后销毁旧的“Java”和“Script”字符串。然而,在IE6等低版本浏览器中,这种字符串拼接方式会消耗大量性能。

模拟Java StringBuffer机制

这让人联想到Java中的字符串机制,同样具有不可变性,但Java提供了StringBuffer类来解决频繁拼接的性能问题,而原生JavaScript并未提供类似的标准方法。不过,我们可以通过模拟这种缓冲机制来优化性能,其核心原理是利用数组进行拼接,具体源代码如下:

代码如下:

function StringBuffer() {
this.__strings__ = new Array();
}
StringBuffer.prototype.append = function (str) {
this.__strings__.push(str);
return this; //方便链式操作
}
StringBuffer.prototype.toString = function () {
return this.__strings__.join("");
}
/*测试*/
var buffer = new StringBuffer();
buffer.append("Hello ").append("javascript");
var result = buffer.toString();
alert(result);

ps:gist地址如下:https://gist.github.com/hehongwei44/fe71f10e4d2d9295aeab

性能测试与IE6优化建议

虽然模拟出了该机制,但其与原生字符串拼接的性能差异究竟如何?我们可以通过以下测试代码进行验证:

代码如下:

var d1 = new Date();
var str = "";
for(var i = 0; i < 10000; i++){
str += "text ";
}
var d2 = new Date();
document.write("测试一花费: " + (d2.getTime() - d1.getTime())/1000 + "秒"+"<br/>");
var oBuffer = new StringBuffer();
d3 = new Date();
for(var i = 0; i < 10000; i++){
 oBuffer.append("text ");
}
var sResult = oBuffer.toString();
d4 = new Date();
document.write("测试二花费: " + (d4.getTime() - d3.getTime())/1000 + "秒");

测试结果如下:(环境不同,测试结果可能不同):

1.在以1000次为基数的情况下,进行比较,两者执行都非常快(基本都是几毫秒)耗时都差不多,后者以前者相差不会超过10个毫秒。 2.在以10000次为基数的情况下,执行结果和上面差不多,但是前者在IE6下话费的事件较多。 3.在以100000次为基数的情况下,字符串拼接在IE6下,明显花的时间更多,其他浏览器相差不大,有的反而比StringBuffer更短。

结论

1.在拼接词数少于1000次的情况下,大胆的使用前者,一般我们也很少碰到拼接次数上千的情况。 2.其他浏览器对于拼接都没什么性能问题,主要是IE6,如果拼接次数上万或者十万的话,建议单独对IE6是用StringBuffer模拟。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章