跳轉到內容

JavaScript/最佳化

來自華夏公益教科書,自由的教科書



TODO
待辦事項

編輯注
以下僅為大綱,待完善。


JavaScript 最佳化

[編輯 | 編輯原始碼]

最佳化技巧

[編輯 | 編輯原始碼]
  • 高階最佳化
    • 演算法最佳化(數學分析)
    • 簡化
  • 低階最佳化
    • 迴圈展開
    • 強度削減
    • Duff's Device
    • 清理迴圈
  • 外部工具和庫,用於加速/最佳化/壓縮 JavaScript 程式碼

常見錯誤和誤解

[編輯 | 編輯原始碼]

字串連線

[編輯 | 編輯原始碼]

JavaScript 中的字串是不可變物件。這意味著,一旦建立了字串物件,要修改它,理論上必須建立一個新的字串物件。

現在,假設您想對一個長字串中的所有字元執行 ROT-13 操作。假設您有一個 rot13() 函式,那麼完成此操作的明顯方法可能是

var s1 = "the original string";
var s2 = "";

for (i = 0; i < s1.length; i++) {
  s2 += rot13(s1.charAt(i));
}

特別是在 Internet Explorer 6 等較舊的瀏覽器中,這將非常緩慢。這是因為,在每次迭代中,必須複製整個字串,然後才能附加新字母。

一種使此指令碼更快的辦法可能是建立一個字元陣列,然後將其連線起來

var s1 = "the original string";
var a2 = new Array(s1.length);
var s2 = "";

for (i = 0; i < s1.length; i++) {
  a2[i] = rot13(s1.charAt(i));
}
s2 = a2.join('');

Internet Explorer 6 將更快地執行此程式碼。但是,由於原始程式碼非常直觀且易於編寫,因此大多數現代瀏覽器都改進了對這種連線的處理。在某些瀏覽器上,原始程式碼可能比此程式碼更快。

提高此程式碼速度的第二種方法是將要寫入的字串分解。例如,如果這是普通文字,空格可能是一個很好的分隔符

var s1 = "the original string";
var c;
var st = "";
var s2 = "";

for (i = 0; i < s1.length; i++) {
  c = rot13(s1.charAt(i));
  st += c;
  if (c == " ") {
    s2 += st;
    st = "";
  }
}
s2 += st;

這樣,新字串的大部分被複制的頻率要低得多,因為單個字元被新增到較小的臨時字串中。

在 for 迴圈中真正提高速度的第三種方法是將 [陣列] .length 語句移到條件語句之外。事實上,每次出現時,[陣列] .length 都會重新計算。對於兩個出現次數的迴圈,結果將不可見,但(例如)在五千次出現次數的迴圈中,您將看到差異。可以用簡單的計算來解釋

// we assume that myArray.length is 5000
for (x = 0;x < myArray.length;x++){
// doing some stuff
}

"x = 0" 僅評估一次,因此僅為一次操作。

"x < myArray.length" 評估了 5000 次,因此為 10,000 次操作(myArray.length是操作,比較myArray.length與 x 相比,是另一項操作)。

"x++" 評估了 5000 次,因此為 5000 次操作。

總共有 15 001 次操作。

// we assume that myArray.length is 5000
for (x = 0, l = myArray.length; x < l; x++){
// doing some stuff
}

"x = 0" 僅評估一次,因此僅為一次操作。

"l = myArray.length" 僅評估一次,因此僅為一次操作。

"x < l" 評估了 5000 次,因此為 5000 次操作(l 與 x 相比,是一次操作)。

"x++" 評估了 5000 次,因此為 5000 次操作。

總共有 10002 次操作。

因此,為了最佳化您的 for 迴圈,您需要編寫以下程式碼

var s1 = "the original string";
var c;
var st = "";
var s2 = "";

for (i = 0, l = s1.length; i < l; i++) {
  c = rot13(s1.charAt(i));
  st += c;
  if (c == " ") {
    s2 += st;
    st = "";
  }
}
s2 += st;
華夏公益教科書