javascript
《高性能JavaScript》第五章 字符串和正则表达式
5.1 字符串連接
當連接少量字符串時,這些方法運行速度都很快。隨著要合并的字符串長度和數量增加時,有些方法就開始展現優勢。
5.1.1 加(+)和加等(+=)操作符
這是一個常見的字符串連接:
str += "one" + "two";這段代碼運行時,會經歷四個步驟:
1:在內存中創建一個臨時字符串;
2:連接后的“onetwo”被賦值給該臨時字符串;
3:臨時字符串與str當前的值連接;
4:結果賦值給str。
以下優化會提速10%~40%,原因是這樣做避免使用了臨時字符串:
5.1.2 數組項合并
Array.prototype.join()方法將數組中的所有元素合并成一個字符串,它接收一個字符串參數為分隔符插入每個元素中間。如果傳入的分隔符為空字符"",則可以將數組的所有元素連接起來。
注意:在大多數瀏覽器中,數組項合并比其他字符串連接方法更慢,而在IE 7以及更早的版本上合并大量字符串唯一高效的方法,謹慎使用。
5.1.3 String.prototype.concat
字符串原生方法concat能接收任意數量的參數,并將每一個參數附加到所調用的字符串上。
// 附加一個字符串str = str.concat(s1);// 附加兩個字符串str = str.concat(s1, s2, s3);// 如果傳遞一個數組,可以附加數組中的所有字符串str = String.prototype.concat.apply(str, array);注意:遺憾的是,多數情況下concat比使用簡單的+和+=稍慢,并且還潛伏著災難性的性能問題,不建議使用。
5.2 正則表達式優化
本節包含了大量概念以及理解性內容,建議閱讀原書。此次只做簡單的介紹。
5.2.1 正則表達式工作原理
第一步:編譯
當你創建了一個正則表達式對象之后(使用一個正則表達式直接量或者RegExp構造器),瀏覽器檢查你的模板有沒有錯誤,然后將它轉換成一個本機代碼例程,用于執行匹配工作。如果你將正則表達式賦給一個變量,你可以避免重復執行此步驟。
第二步:設置起始位置
當一個正則表達式投入使用時,首先要確定目標字符串中開始搜索的位置。它是字符串的起始位置,或者由正則表達式的 lastIndex 屬性指定,但是當它從第四步返回到這里的時候(因為嘗試匹配失敗),此位置將位于最后一次嘗試起始位置推后一個字符的位置上。
瀏覽器廠商優化正則表達式引擎的辦法是,在這一階段中通過早期預測跳過一些不必要的工作。例如,如果一個正則表達式以^開頭,IE 和 Chrome 通常判斷在字符串起始位置上是否能夠匹配,然后可避免愚蠢地搜索后續位置。另一個例子是匹配第三個字母是 x 的字符串,一個聰明的辦法是先找到 x,然后再將起始位置回溯兩個字符(例如,最近的 Chrome 版本實現了這種優化)。
第三步:匹配每個正則表達式的字元
正則表達式一旦找好起始位置,它將一個一個地掃描目標文本和正則表達式模板。當一個特定字元匹配失敗時,正則表達式將試圖回溯到掃描之前的位置上,然后進入正則表達式其他可能的路徑上。
第四步:匹配成功或失敗
如果在字符串的當前位置上發現一個完全匹配,那么正則表達式宣布成功。如果正則表達式的所有可能路徑都嘗試過了,但是沒有成功地匹配,那么正則表達式引擎回到第二步,從字符串的下一個字符重新嘗試。只有字符串中的每個字符(以及最后一個字符后面的位置)都經歷了這樣的過程之后,還沒有成功匹配,那么正則表達式就宣布徹底失敗。
5.2.2 理解回溯
這個表達式匹配“hello hippo”或“happy hippo”。
/h(ello|appy) hippo/.test("hello there, happy hippo");回溯過程如下:
貪婪量詞和惰性量詞回溯:
5.2.3 提高效率的方法
1:關注如何讓匹配更快失敗;
2:表達式以簡單、必須的字元開始;
3:使用量詞模式,使它們后面的字元互斥;
4:減少分支數量,縮小分支范圍;
5:使用非捕獲組;
6:只捕獲感興趣的文本以減少后處理;
7:暴露必需的字元;
8:使用合適的量詞;
9:把表達式賦值給變量并重用;
10:將復雜的表達式拆分為簡單的片段。
總結
以上是生活随笔為你收集整理的《高性能JavaScript》第五章 字符串和正则表达式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《高性能JavaScript》第四章 算
- 下一篇: 《高性能JavaScript》第六章 快