1. 程式人生 > 實用技巧 >使用物件提高字串連線的效能

使用物件提高字串連線的效能

物件令人感興趣的一點是用它們解決問題的方式。ECMAScript 中最常見的一個問題是字串連線的效能

var str = "hello ";
str += "world";

實際上,這段程式碼在幕後執行的步驟如下:

  1. 建立儲存 "hello " 的字串。
  2. 建立儲存 "world" 的字串。
  3. 建立儲存連線結果的字串。
  4. 把 str 的當前內容複製到結果中。
  5. 把 "world" 複製到結果中。
  6. 更新 str,使它指向結果。

每次完成字串連線都會執行步驟 2 到 6,使得這種操作非常消耗資源。如果重複這一過程幾百次,甚至幾千次,就會造成效能問題。解決方法是用 Array 物件儲存字串,然後用 join() 方法(引數是空字串)建立最後的字串。想象用下面的程式碼代替前面的程式碼:

var arr = new Array();
arr[0] = "hello ";
arr[1] = "world";
var str = arr.join("");

這樣,無論陣列中引入多少字串都不成問題,因為只在呼叫 join() 方法時才會發生連線操作。此時,執行的步驟如下:

  1. 建立儲存結果的字串
  2. 把每個字串複製到結果中的合適位置

雖然這種解決方案很好,但還有更好的方法。問題是,這段程式碼不能確切反映出它的意圖。要使它更容易理解,可以用 StringBuffer 類打包該功能:

function StringBuffer () {
  this._strings_ = new Array();
}

StringBuffer.prototype.append 
= function(str) { this._strings_.push(str); }; StringBuffer.prototype.toString = function() { return this._strings_.join(""); };

這段程式碼首先要注意的是 strings 屬性,本意是私有屬性。它只有兩個方法,即 append() 和 toString() 方法。append() 方法有一個引數,它把該引數附加到字串陣列中,toString() 方法呼叫陣列的 join 方法,返回真正連線成的字串。要用 StringBuffer 物件連線一組字串,可以用下面的程式碼:

var buffer = new StringBuffer ();
buffer.append("hello ");
buffer.append("world");
var result = buffer.toString();

可用下面的程式碼測試 StringBuffer 物件和傳統的字串連線方法的效能:

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

console.log("Concatenation with plus: " + (d2.getTime() - d1.getTime()) + " milliseconds");

var buffer = new StringBuffer();
d1 = new Date();
for (var i=0; i < 10000000; i++) {
    buffer.append("text");
}
var result = buffer.toString();
d2 = new Date();

console.log("<br />Concatenation with StringBuffer: " + (d2.getTime() - d1.getTime()) + " milliseconds");

這段程式碼對字串連線進行兩個測試,第一個使用加號,第二個使用 StringBuffer 類。每個操作都連線 10000 個字串。日期值 d1 和 d2 用於判斷完成操作需要的時間。請注意,建立 Date 物件時,如果沒有引數,賦予物件的是當前的日期和時間。要計算連線操作歷經多少時間,把日期的毫秒錶示(用 getTime() 方法的返回值)相減即可。這是衡量 JavaScript 效能的常見方法。該測試的結果可以幫助您比較使用 StringBuffer 類與使用加號的效率差異。