`
sisi1984117
  • 浏览: 156109 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

【转】如何摆脱JS糟糕的字符串连接

 
阅读更多
一、ECMAScript的字符串是不可变的,即它们的值不能改变,因此当你写出下面的代码的时候发生了什么呢?
Js代码  
var str = "Hello ";    
str += "world";  
var str = "Hello ";
str += "world";
 执行的步骤如下:
创建存储“Hello“的字符串 
创建存储”world“的字符串 
创建存储连接结果的字符串 
把str的当前内容复制到结果中 
把“world”复制到结果中 
更新str,使它指向结果 
    每次完成字符串的连接都会执行步骤2-6,使得这种操作非常消耗资源。想象一下重复这个过程几百次,甚至几千次,那性能如何?
 
二、那么再看看下面的代码,来解决这种窘况
Js代码   
var arr = new Array; 
arr[0] = "Hello ";    
arr[1] = "world";    
var str = arr.join("");   
var arr = new Array;
arr[0] = "Hello ";
arr[1] = "world";
var str = arr.join(""); 
执行的步骤如下:
创建存储结果的字符串 
把每个字符串复制到结果中的适当位置 
这样,无论数组要引入多少字符串都不成问题,因为只有在调用join()方法时候才会发生连接操作。
 
三、觉得操作很复杂?代码不能确切反应它的意图?那么我们用对象的解决方式吧,使它更容易理解,用StringBuffer类来封装该功能:
Js代码  
    function StringBuffer() {   
 this._strs = new Array;    
}    
   
StringBuffer.prototype.append = function (str) {    
    this._strs.push(str);    
};    
   
StringBuffer.prototype.toString = function() {    
    this._strs.join("");    
};  
function StringBuffer() {
    this._strs = new Array;
}
StringBuffer.prototype.append = function (str) {
    this._strs.push(str);
};
StringBuffer.prototype.toString = function() {
    this._strs.join("");
};
    好了,感受一下吧,现在如何操作字符串呢?
Js代码 
var sb = new StringBuffer();  
 sb.append("Hello ");    
sb.append("world");    
var result = sb.toString();  
var sb = new StringBuffer();
sb.append("Hello ");
sb.append("world");
var result = sb.toString();
 四、似乎色香味俱全了,但是吃下去的功效如何? Js代码 
var tStart = new Date();    
var str = "";    
for(var i=0;i<10000;i++)    
{    
   str += "text"   
}    
var tEnd = new Date();    
   
document.write("原始的方法加号 拼接10000个字符串 花费时间:"+(tEnd.getTime()-tStart.getTime())+"秒");    
   
   
var oSB = new StringBuffer();    
tStart = new Date();    
for(var i=0;i<10000;i++)    
{    
    oSB.append("text");    
}    
var sRst = oSB.toString();    
tEnd = new Date();    
   
document.write("<br/>StringBuffer 拼接10000个字符串 花费时间:"+(tEnd.getTime()-tStart.getTime())+"秒");  
var tStart = new Date();
var str = "";
for(var i=0;i<10000;i++)
{
   str += "text"
}
var tEnd = new Date();
document.write("原始的方法加号 拼接10000个字符串 花费时间:"+(tEnd.getTime()-tStart.getTime())+"秒");
var oSB = new StringBuffer();
tStart = new Date();
for(var i=0;i<10000;i++)
{
    oSB.append("text");
}
var sRst = oSB.toString();
tEnd = new Date();
document.write("<br/>StringBuffer 拼接10000个字符串 花费时间:"+(tEnd.getTime()-tStart.getTime())+"秒");
   可能你已经猜到了,StringBuffer要比+快,到底快多少呢?我的测试结果: 
 Js代码 
FF3.0.10    
原始的方法加号 拼接10000个字符串 花费时间:3豪秒    
StringBuffer 拼接10000个字符串 花费时间:8豪秒     
   
IE7    
原始的方法加号 拼接10000个字符串 花费时间:15豪秒    
StringBuffer 拼接10000个字符串 花费时间:16豪秒     
   
IE8    
原始的方法加号 拼接10000个字符串 花费时间:15豪秒    
StringBuffer 拼接10000个字符串 花费时间:16豪秒    
   
Chrome1.0.154.46    
原始的方法加号 拼接10000个字符串 花费时间:1豪秒    
StringBuffer 拼接10000个字符串 花费时间:2豪秒  
FF3.0.10
原始的方法加号 拼接10000个字符串 花费时间:3豪秒
StringBuffer 拼接10000个字符串 花费时间:8豪秒 
IE7
原始的方法加号 拼接10000个字符串 花费时间:15豪秒
StringBuffer 拼接10000个字符串 花费时间:16豪秒 
IE8
原始的方法加号 拼接10000个字符串 花费时间:15豪秒
StringBuffer 拼接10000个字符串 花费时间:16豪秒
Chrome1.0.154.46
原始的方法加号 拼接10000个字符串 花费时间:1豪秒
StringBuffer 拼接10000个字符串 花费时间:2豪秒
 
五、怎么回事? 
    恩?眼睛花了?还是测试结果贴错了?还是……? 
    一切都没有错! 
    2006年11月此书出版《JavaScript高级程序设计》在84-85页,就是我上面的内容,我的测试结果却和它的完全相反,技术的变革还是……? 
    我觉得是一个教训!深刻的教训!不知道哪看了这篇文章的人会有何感想。
摘自【http://jiajun.iteye.com/blog/377605】
 
【PS:】数组方法解决JS字符串连接性能问题有争议
1、传统上,字符串连接一直是js中性能最低的操作之一。
     var text="Hello";
     text+=" World!";
     早期浏览器没有对这种运算进行优化。
     由于字符串是不可变的,这意味着要创建中间字符串来存储连接的结果。频繁地在后台创建和销毁字符串导制性能异常低下。
2、发现这一点后,开发者们利用数组对象进行优化。
     var buffer=[],i=0;
     buffer[i++]="Hello";//通过相应索引值添加元素比push方法快
     buffer[i++]=" World!";
     var text=buffer.join("");
     在早期的浏览器中,没有创建和销毁中间字符串,在大量字符串连接情况下,这技术已被证明远快于使用加法方式。
3、如今浏览器对字符串的优化已经改变了字符串相连的局面。
    Safari、Opera、Chrome、Firefox和IE8都在使用加法运算符上表现出了更好的性能。但是,IE8之前的版本没有优化,因此数组方法依然有效。
    这并不意味着字符串相连时我们要进行浏览器检测。在决定如何连接时要考虑的是字符串的大小和数量。
    1)当字符串相对较小(<20字符)且连接数量也较小时(<1000个),所有的浏览器使用加法运算符都能在不到1豪秒内轻松完成连接。
    2)增加字符串数量或大小时,IE7中性能会明显下降。
    3)字符串大小增加时,Firefox中加法运算符和数组成技巧性能差异会变小。
    4)字符串数量增加时,Safari中加法运算符和数组成技巧性能差异会变小。
    5)改变字符串数量或大小时,Chrome和Opera中加法运算符一直保持领先优势。
    所以,由于在各浏览器下性能不一致,选用技术取决于实际情况和面对的浏览器。
    大多数情况下,加法运算符是首选;如果用户主要使用IE6或7,并且字符串大小较大或数量较多时,那么数组技术就很值得。
摘自:【http://www.cnblogs.com/a-jian/archive/2011/01/12/1933703.html】
分享到:
评论

相关推荐

    java开源包4

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    JAVA上百实例源码以及开源项目源代码

    设定字符串为“张三,你好,我是李四” 产生张三的密钥对(keyPairZhang) 张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节 通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后...

    java开源包1

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包11

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包2

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包3

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包6

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包5

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包10

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包8

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包7

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包9

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    java开源包101

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

    Java资源包01

    JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接...

Global site tag (gtag.js) - Google Analytics