Наложи ми се да филтрирам лог файл на apache и като най-добър (лесен и бърз) вариант избрах grep и regular expression. За няколко минути установих, че има сериозна разлика в бързината на изпълнение на различните регулярни изрази предлагани от grep. Става дума за extended и Perl.
В общи линии регулярният израз, който ми свърши цялата работа е ‘^[0-9\.]+ \- \- \[[0-9]+/Jul’ – извежда всички налични редове за месец Юли. Може би регулярния израз не е перфектен, но с този му формат се застраховах от евентуални грешки.
Резултата
При употребата на extended (-E) се достига скорост от околу 300 реда в секунда, докато при употребата на Perl (-P) достигната скорост е средно 20’000 реда в секунда.
Как точно го премери това чудо ? Интересно ми е как успя да отделиш времето през което диска ти е чел лога от времето през което процесора е смятал regex-а 🙂
освен това 300 реда/сек е просто смешно …
cat access_log | wc -l
10708
time cat access_log | grep -E “\[[0-9]+\/Sep”
…
real 0m0.197s
user 0m0.019s
sys 0m0.043s
а машината е:
model name : Pentium III (Coppermine)
cpu MHz : 647.370
което пък никак не се връзва с тези твърдения за 300 реда/сек …
wc -l access_log
1911437
time grep -E ‘^[0-9\.]+ \- \- \[[0-9]+/Jul’ access_log
real 2m2.065s
user 2m1.256s
sys 0m0.392s
time grep -E ‘\[[0-9]+/Jul’ access_log
real 0m28.538s
user 0m27.898s
sys 0m0.380s
time grep -P ‘^[0-9\.]+ \- \- \[[0-9]+/Jul’ access_log
real 0m8.903s
user 0m1.564s
sys 0m0.160s
time grep -P ‘\[[0-9]+/Jul’ access_log
real 0m9.232s
user 0m0.196s
sys 0m0.052s
Процесор:
Quad-Core AMD Opteron 1900.077MHz
uptime
5:35pm up 30 days 5:38, 1 user, load average: 0.01, 0.12, 0.18
Предния път си играх с седем пъти по-голям лог – възможно е това също да създава някакво разминаване. Използвания от мен по-горе лог е само за месец Септември.
Разликата както се вижда е доста ясно:)
Да добява и това:
cat /etc/SuSE-release
openSUSE 10.3 (X86-64)
VERSION = 10.3
В интерес на истината в къщи имам същата машина Pentium III (Coppermine) на 696.997MHz. Трябва да бутна някое логче там и да пробвам.
ако ще правиш тестове на бързината на grep се абстрахирай от диска … в случая вадиш заключения на базата на грешна тестова постановка …
съгласен съм че egrep е по-бавен, но е абсурдо твърдението за 66 пъти разлика …
в твоите примери си пуснал egrep в началото … ако не си “изчел” преди това този файл това определено ще доведе до внасянето на огромна грешка (забавяне) при четенето от диска …
при повторното пускане на egrep-а с другия pattern съм вече по-склонен да се съглася … би било хубаво да повтаряш по няколко пъти едно и също за да сведеш до минимум случайните грешки (като например cashe flush) … още по-хубаво би било ако го качиш в някой RAM диск …
в случая броя на core-тата на CPU-тата е без голямо значение … имаш 1 процес в примерите които си дал … CPU cache и RAM това се иска …
и btw regex-a изглежда загадъчно и красиво … но няма нужда да го блъскаш с много правила … keep it simple 🙂
Както писах в поста идеята да “разкрася” регулярния израз бе да се застраховам от грешки (наличието на “неприлични” символи в Get адреса) В крайна сметка за теста вършат работа и двете (разбира се по-“красивия” е по-бавен по разбираеми причини).
Това за tmpfs-a е добра идея, имам едни заделени 256мб ще ги опъна за теста.
Въпреки всичко забавянето при четене на диска е достатъчно еднакво и за extended и за perl pattern-a. Не смятам, че от там идва разликата между двете:)
дали ?
твърдението ти е вярно … НО само след първото прочитане на въпросния файл, и при положение че нямаш други “гладни” за RAM процеси … ако имаш достатъчно RAM твърде е вероятно въпросния файл да се “cache” … айде поздрави и копай повече (ударение е на О-то) 🙂
Копам, копам;)
Тествания файл е 448M, рама total 384МБ
(става дума за XEN сървър)
В крайна сметка до нищо по-различно не доведаха и допълнителните тестове:
time grep -E ‘\[[0-9]+/Jul’
real 0m29.342s
real 0m28.208s
real 0m28.631s
real 0m30.524s
time grep -E ‘^[0-9\.]+ \- \- \[[0-9]+/Jul’
real 2m1.908s
real 2m6.382s
real 2m0.161s
real 2m4.820s
(тестовете са поред – първо пускам 4 пъти еидния, след което 4 пъти другия)