Я довольно новичок в 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
Я нахожу, что это работает примерно в 20 раз медленнее, чем версия Perl. Я запускал тестовые файлы, предварительно компилируя регулярные выражения и компилируя их «на лету», и существует незначительная разница, поэтому я знаю, что Python не тратит время на компиляцию регулярных выражений. Мое подозрение в том, что он тратит все свое время на уничтожение и компиляцию строк каждый раз, когда я делаю «re.sub».
Итак, простой вопрос - есть ли идиома, чтобы сделать замену быстрее?
Я думаю, я всегда мог попробовать написать функцию, чтобы сделать это без назначения .... это то, что часто используется подход? Можно преобразовать строку в список, а затем через нее, стиль строки C/C++ (ну, я просто выбрасываю это там ...)
Это может быть важно (и именно поэтому я не используйте Counter() в примере). Мне нужно написать это в Python 2.6.4. Если бы это было намного быстрее в 2.7 или 3, просто скажите это. Но у меня нет выбора.
1 символьные регулярные выражения могут быть ускорены с помощью 'str.replace' или' str.translate (None, ':') ' – mgilson
Действительно, пропуская ненужные вызовы' re.sub', нужно ускорить скрипт примерно в три раза , не говоря уже о преимуществах чтения. Но лично я бы сделал это в Awk, а не на Python, если бы это было быстро. –
Интересно - я обрезал syslog fie назад, я читал назад примерно с 4 000 000 строк до 20 000 строк, а версия Python работает примерно столько же времени, сколько и версия Perl. Итак: – wsanders