簡體   English   中英

正則表達式執行時間在第100個模式后急劇跳躍

[英]regular expression execution time jumps sharply after 100th pattern

我從下面的第一個代碼片段開始搜索行列表,並將每行中的所有關鍵字(在單獨的列表中標識)轉換為小寫。 對於我的大約800行長的測試列表,只要我的關鍵字列表是100個項目或更少,整個行列表的關鍵字替換只需不到一秒。 當我將列表擴展到101個或更多項時,處理時間會超過9秒。

使用第二個片段(編譯關鍵字列表的所有模式)會將總處理時間減少到1秒以下。

有誰知道為什么非編譯替換搜索的處理時間對每個輸入行搜索的項目數如此敏感? 在100個關鍵詞之后,我很驚訝它跳得那么厲害。

片段#1

for line in lines_in:
    for keyword in keywords:
        rawstring = r'\b' + keyword + r'\b'
        line = re.sub(rawstring, keyword, line, 0, re.IGNORECASE)

片段#2

for i in range(len(keywords)):
    re_pattern = re.compile(r'\b' + keywords[i] + r'\b', re.IGNORECASE)
    pattern.append(re_pattern)

for line in lines_in:
    for i in range(len(keywords)):
        line = pattern[i].sub(keywords[i], line, 0)

這是因為Python內部緩存編譯正則表達式,而內部緩存的大小為100(可以看出這里上線227此外,您可以在線246-247看出,當緩存獲得的在最大尺寸是清除而不是使用更高級的緩存失效算法。這實際上意味着循環的每次迭代都會耗盡緩存並導致重新編譯所有100多個正則表達式。

在第二個示例中,性能恢復到“正常”,因為它不依賴於內部緩存保持原樣以保持編譯的正則表達式。

這是由於re模塊中編譯的正則表達式的內部緩存。 如果你在代碼中使用了很多正則表達式,那么預編譯它們而不是直接使用re.match或re.search,它會更快。

內部重新緩存是為了方便快速的常見簡單用例,而不是高性能。

re.compile的文檔說:

注意傳遞給re.match(),re.search()或re.compile()的最新模式的編譯版本被緩存,因此一次只使用幾個正則表達式的程序不必擔心定期編譯表達式。

我想我們現在知道緩存的大小了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM