我對Python相當陌生。我正在構建一個腳本來瀏覽一個日誌文件,就像我在Perl中做了上百次一樣。我使用的是哈希計算某些字段出現在日誌文件中,就像我已經做了一百時間在Perl,一拉:Python re.sub考慮慢?
for $line in (<FILE>) {
($stuff1, $stuff2, $etc) = split(/\s+/, $line);
$stuff1 =~ s/something//;
$stuff2 =~ s/something//;
$count1{$stuff1}++;
$count2{$stuff2}++;
}
etc, print the hashes
我的Python是這樣的:
import re
from collections import defaultdict
cntdaemon = defaultdict(int)
cntfaclevel = defaultdict(int)
cnthost = defaultdict(int)
redaemon1 = re.compile('\[[0-9]+\]')
redaemon2= re.compile(':')
refaclevel= re.compile(']')
with open("/var/adm/messages", 'r') as infile:
for line in infile:
(m, d, t, host, daemon, junk, idno, faclevel, text) = line.split(' ',8)
daemon = re.sub(redaemon1, '', daemon)
daemon = re.sub(redaemon2, '', daemon)
cntdaemon[daemon] += 1
faclevel = re.sub(refaclevel, '', faclevel)
cntfaclevel[faclevel] += 1
cnthost[host] += 1
print cntdaemon
print cntfaclevel
print cnthost
我發現這個版本比Perl版本慢20倍左右。我已經運行了預編譯正則表達式的測試用例,並對其進行了「即時編譯」,並且可以忽略不計,所以我知道Python不會浪費時間編譯正則表達式。我懷疑是每次我做一個「re.sub」的時候,它會花費我所有的時間來銷燬和編譯字符串。
所以,簡單的問題 - 有一個成語做替代更快?
我想我總是可以嘗試寫一個函數來做到這一點,而不分配....是一種方法往往採取?人們可以通過它的字符串轉換成一個列表,然後ITER,C/C++字符串風格(當然,我只是那個扔在那裏...)
這可能是重要的(也就是爲什麼我不在示例中使用Counter()) - 我需要在Python 2.6.4中編寫它。如果這在2.7或3中會快得多,就這麼說吧。但我沒有選擇。
1個字符的正則表達式可以通過'str.replace'或'str.translate(None,':')''加快速度。 – mgilson
實際上,跳過不必要的're.sub'調用應該可以使腳本速度提高三倍,更不用說可讀性的好處了。但個人而言,如果它必須快速,我會在Awk中做這種事情,而不是Python。 –
有趣 - 我修剪系統日誌外商投資企業後,我是從約4,000,000行讀回至20000線和Python版本在大約相同的時間量Perl的版本上運行。所以: – wsanders