你不得不知道的關於JavaScript 中字串串連的效能問題

來源:互聯網
上載者:User

每種程式語言中都會涉及到字元竄串連,而這個小小的字元竄串連問題很可能會影響到系統的整體效能,本文主要探討JavaScript中字串串連的效能問題。而JavaScript的核心是ECMAScript 。與其他語言類似,ECMAScript 的字串是不可變的,即它們的值不能改變。請考慮下面的代碼:

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

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

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

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

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 對象和傳統的字串串連方法的效能,在chrome控制台輸入一下代碼並運行:

var d1 = new Date();var str = "";for (var i=0; i < 10000; 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 < 10000; i++) {    buffer.append("text");}var result = buffer.toString();d2 = new Date();console.log("Concatenation with StringBuffer: " + (d2.getTime() - d1.getTime()) + " milliseconds");

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

那麼有人也許會說JavaScript的String對象中不是也封裝一個concat()方法麼,我們在下面也來用concat()方法來做同樣的事情,在consoel輸入以下代碼:

var d1 = new Date();var str = "";for (var i=0; i < 10000; i++) {    str.concat("text");}var d2 = new Date();console.log("Concatenation with plus: " + (d2.getTime() - d1.getTime()) + " milliseconds");

我們可以看到做10000次字元竄串連它的耗時是:

由此可以得出結論,當涉及到一定數量的字串串連時,我們在Javascript中封裝一個類似Java中的StringBuffer對象(函數)來進行操作會在效能上得到提升。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.