grep為什么那么快

grep簡介

在Linux里面园骆,如果按照使用頻率給命令排個序分俯,那么grep絕對榜上有名蹈垢。

grep的全稱是Global Expression Print畜伐,用于正則表達式匹配文本丈咐,并把匹配到的行打印出來瑞眼。

命令的基本形式是:

grep [option] pattern file

此處的file并不一定是特指某個文件,準確來說是指棵逊,任何的輸入流伤疙。所以時常grep會合別的命令結(jié)合在一起來使用,例如查找Java進程:

ps -ef | grep java

在我機器上的輸出是:

501 25223 16384   0  7:05下午 ttys002    0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn java

grep作為一個基本工具辆影,其性能是極高的:


image

現(xiàn)在我們就要思考一下掩浙,為什么grep會那么快呢?

grep那么快秸歧,就兩個原因:

  • 快的算法
  • 快的輸入厨姚。

我們先討論快的算法。

字符串檢索

我們先來了解一下字符串搜索键菱,即如何在一個字符串中找到我們所需要的字符串谬墙,或者說子串。這些字符串一般都是符合某個規(guī)則经备,通常而言是使用正則表達式來進行描述拭抬。

在字符串檢索里面,鼎鼎有名的就是Boyer-Moore字符串檢索算法了額侵蒙。這個算法阮一峰有過很精彩很簡潔的介紹造虎,地址是:

http://www.ruanyifeng.com/blog/2013/05/boyer-moore_string_search_algorithm.html

也可以閱讀Moor教授對算法的介紹:

http://www.cs.utexas.edu/~moore/best-ideas/string-searching/fstrpos-example.html

我這里總結(jié)一下阮一峰文章的精髓:

這個算法的核心是“壞字符規(guī)則”和“好后綴規(guī)則”。

壞字符規(guī)則

壞字符是指纷闺,無法匹配上模式的字符算凿,例如:


image

S和E無法匹配上份蝴,也就是一個壞字符。
而所謂壞字符規(guī)則就是:

后移位數(shù) = 壞字符的位置 - 搜索詞中的上一次出現(xiàn)位置

所以下一次的匹配應(yīng)該變成了:


image

氓轰;

在上圖的情況下婚夫,可以進一步將字符串后移,將P對齊:


image

好后綴規(guī)則

image

這種所有尾部都匹配的字符串就叫做好后綴署鸡。當(dāng)好后綴遇到第一個不匹配的字符的時候案糙,在上圖中也就是I和A,那么移動位數(shù)是:

后移位數(shù) = 好后綴的位置 - 搜索詞中的上一次出現(xiàn)位置

這就是Boyer-Moor算法的核心靴庆。

我們可以簡單分析一下Boyer-Moor算法的效率时捌。它是O(n)的,但是很多情況下炉抒,它并不需要遍歷文本里面的每一個字符匣椰。

實現(xiàn)技巧

主要是使用了兩個技巧:

  1. 循環(huán)展開。GNU grep將Boyer-Moor算法的內(nèi)層循環(huán)展開了端礼;
  2. 建立了一個jump table禽笑,也叫做delta table。通過該表可以避免進行循環(huán)退出判斷了蛤奥;

快的輸入

grep在這方面所進行的優(yōu)化佳镜,即使用系統(tǒng)調(diào)用,以避免數(shù)據(jù)拷貝的開銷凡桥。

這是一種常見的優(yōu)化手段蟀伸,比如在Java NIO里面也使用到了類似的技術(shù)手段以避免數(shù)據(jù)從內(nèi)核態(tài)拷貝到用戶態(tài),再由用戶態(tài)拷貝到內(nèi)核態(tài)

第二個優(yōu)化是避免了對輸入進行分行缅刽。grep直接將文本放在Buffer之中進行處理啊掏,在找到了匹配的字符串之后,再去查找里面有沒有換行符衰猛。因為查找換行符是一個可怕的操作迟蜜,這意味著需要逐個字符查找。

后記

原文是https://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html#

郵件里面還提到一個東西啡省,即Fast String Search娜睛,這是一個關(guān)于Boyer-Moor算法實現(xiàn)優(yōu)化的論文。我表示這篇論文沒怎么讀懂卦睹,我就不誤人子弟了畦戒。

下載鏈接是:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.13.9460&rep=rep1&type=pdf

可以翻墻的同志可以看這個視頻,對Boyer-Moor算法的講解還是很好的:

https://www.youtube.com/watch?v=4Xyhb72LCX4
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末结序,一起剝皮案震驚了整個濱河市障斋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖垃环,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邀层,死亡現(xiàn)場離奇詭異,居然都是意外死亡晴裹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門救赐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涧团,“玉大人,你說我怎么就攤上這事经磅∶谛澹” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵预厌,是天一觀的道長阿迈。 經(jīng)常有香客問我,道長轧叽,這世上最難降的妖魔是什么苗沧? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮炭晒,結(jié)果婚禮上待逞,老公的妹妹穿的比我還像新娘。我一直安慰自己网严,他們只是感情好识樱,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著震束,像睡著了一般怜庸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垢村,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天割疾,我揣著相機與錄音,去河邊找鬼嘉栓。 笑死杈曲,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胸懈。 我是一名探鬼主播担扑,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼趣钱!你這毒婦竟也來了涌献?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤首有,失蹤者是張志新(化名)和其女友劉穎燕垃,沒想到半個月后枢劝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡卜壕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年您旁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轴捎。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鹤盒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侦副,到底是詐尸還是另有隱情侦锯,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布秦驯,位于F島的核電站尺碰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏译隘。R本人自食惡果不足惜亲桥,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望固耘。 院中可真熱鬧两曼,春花似錦、人聲如沸玻驻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽璧瞬。三九已至户辫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嗤锉,已是汗流浹背渔欢。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瘟忱,地道東北人奥额。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像访诱,于是被迫代替她去往敵國和親垫挨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 參考文章 知乎:如何更好的理解和掌握 KMP 算法?從頭到尾徹底理解KMPKMP 算法(1):如何理解 KMP(原...
    Mjolnir1107閱讀 985評論 0 0
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,381評論 0 5
  • 字符串匹配KMP算法詳解 1. 引言 以前看過很多次KMP算法触菜,一直覺得很有用九榔,但都沒有搞明白,一方面是網(wǎng)上很少有...
    張晨輝Allen閱讀 2,400評論 0 3
  • 由于是畢業(yè)后轉(zhuǎn)行的原因,所以本人在工作之前沒有系統(tǒng)的學(xué)過數(shù)據(jù)結(jié)構(gòu)哲泊、算法導(dǎo)論之類的課剩蟀。說白了就是沒有這樣的底蘊,哈哈...
    張晨輝Allen閱讀 698評論 0 0
  • 建議存下來切威,每讀一次育特,進步十分! 1.有人在說某人壞話時,你只微笑先朦。 2.不要把過去的事全讓人知道缰冤。 3.說話的時...
    li冰bing閱讀 186評論 0 0