JS 字符串连接[性能比较]

  一、ECMAScript的字符串是不可变的,即它们的值不能改变,因此当你写出下面的代码的时候发生了什么呢?

  Js代码

  

复制代码 代码如下:

  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("");

  执行的步骤如下:

  创建存储结果的字符串

  把每个字符串复制到结果中的适当位置

  这样,无论数组要引入多少字符串都不成问题,因为只有在调用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("");

  };

  好了,感受一下吧,现在如何操作字符串呢?

  Js代码

  

复制代码 代码如下:

  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())+"秒");

  可能你已经猜到了,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豪秒

  五、怎么回事?

  恩?眼睛花了?还是测试结果贴错了?还是……?

  一切都没有错!

  2006年11月此书出版《JavaScript高级程序设计》在84-85页,就是我上面的内容,我的测试结果却和它的完全相反,技术的变革还是……?

  我觉得是一个教训!深刻的教训!不知道哪看了这篇文章的人会有何感想。