2011-05-28 10 views
1

一組線需要使用不同的命名正則表達式進行解析。正在尋找實用的解決方案來優化python的文本解析速度

每行都會通過每個正則表達式直到找到匹配。 當發現匹配時,代碼應爲每行返回/ yield(命名爲regex,value)對。

文件是2GB +大小,所以我正在尋找一些提高我的解析器速度的想法。

當前代碼通過python執行,但該部分可以更改。 其中一種選擇是將所有內容都轉換爲C,以便從PCRE獲得更多速度,並且速度更快(?)IO,但這是一條很難在未來維持的緩慢路線。

我正在尋找像切實可行的解決方案:

  • 轉換解析器快了一些語言
  • 移動到用Cython多塊
  • 分割文件,並在幾個線程
  • 上運行(?)
+0

不是'解析'這個詞意味着你*不能*使用正則表達式嗎?它們不適合*解析任何形式的*。 – 2011-05-28 11:18:28

+0

不要挑剔,我需要解決的問題,如果你有更好的詞建議解釋我的問題,請建議。 – damir 2011-05-28 11:22:40

+0

我在建議一個更好的解決方案,而不是一個更好的詞。使用任何合適的解析器生成器,編寫自己的簡單遞歸下降解析器,不管其他什麼,但不要使用正則表達式進行解析,它們不是爲此目的而設計的。如果所有圖案共享同一組可能的詞彙記號,則可以將它們用於lexing,這樣您就可以獲得線性掃描速度。 – 2011-05-28 11:26:24

回答

4

在第一種情況下,我就不會擔心切換到另一種語言。替代策略可能會產生更大的收益。 Python使用的正則表達式引擎無論如何都是用C編寫的(iirc)。

  1. 如果可能是您的第一項任務,請優化正則表達式。如何做到這一點取決於你的文字和表達。有文章和例子的look。 @ThomasH也提出了一個很好的觀點。
  2. 優化正則表達式的最簡單方法是將其刪除;看看是否有機會切換到其他測試,如x in yline.endswith()
  3. 嘗試運行您的代碼與pypy。它可以在不修改代碼的情況下提高性能。在你的情況下,雖然收益可能微不足道,因爲性能必然與你的正則表達式和文件io相關。
  4. 跨多個線程/進程並行處理文件將可能是有益的。我建議使用一個進程讀取文件並將行推送到多個進程所在的隊列中。有很多方法可以做到這一點。看看它來到我的腦海http://effbot.org/zone/wide-finder.htm#a-multi-processor-python-solution
3

加速Python中的模式匹配的一個重要一點是嘗試使用單個正則表達式。因此,而不是通過正則表達式對輸入的每一行的一個列表吧,正則表達式中使用|合併成一個,然後一次爲每個行應用此正則表達式:

reg = re.compile(r''' 
    (?<patt1>foo) 
    |(?<patt2>bar) 
''', re.VERBOSE) 

for line in lines: 
    mo = reg.search(line) 
    if mo: 
     yield (mo.lastgroup(), mo.group(mo.lastgroup())) 
+0

的東西,這在我可以做出的一些優化中是有意義的,tnx – damir 2011-05-28 11:18:24

1

的第一件事是,你應該使用re.compile()準備所有的正則表達式。但我想這已經完成了!

另一個要考慮的可能是分層處理:

取決於你有他們可以組織分層的正則表達式的類型。這樣你可以預先過濾線條,只將它們送入正則表達式,你需要檢查。

例如,如果您在正則表達式中搜索諸如「< body attr1 attr2>」之類的標籤,則可能有助於在檢查該行中的「body」的字符串之前檢查它是否真的是標籤。在使用與標記相關的正則表達式之前,您還可以搜索「<」。

如果將多個表達式合併爲一個並檢查匹配,它也可以加快處理速度。如用「{(term1 | term2)}」替換「{term1}」「{term2}」的單個檢查。

然後,您可以嘗試通過定義最小行長度來篩選哪些正則表達式需要檢查。

這樣簡單的東西可以在不切換到其他語言或cpu的情況下加速應用程序。

如果可能的話,你也可以嘗試去多線程。根據CPU的使用情況,你可以在兩個線程中處理其他線程,這可能會加快處理速度。

+0

re表達式被自動編譯通過python內部和次序使用這樣的任何以下任何電話 – damir 2011-05-28 11:16:59

+0

hmm..tnx爲信息,我會嘗試與compile()計時我的分析器,看看它是否改善情況.. – damir 2011-05-28 20:06:45