Стало интересно протестить питон и перл на скорость при работе с большими файлами. Для теста было написано 2 маленьких скрипта, суть скриптов: прочесть лог и создать хэш, в котором ключом является ip (первое поле в строчке лога), а значением все остальные запросы с данного ip.
В качестве лога был использован лог нджинкса, в котором поля разделены :%%:.
Размер файла лога - 1Гб.
#!/usr/bin/perl -w
open(F, "</var/logs/access.log");
while (<F>) {
($ip, $d) = split(/:%%:/, $_, 2);
if (!(exists $host{$ip})) {
$host{$ip} = {};
$host{$ip}{data} = '';
}
$host{$ip}{data} .= $d;
}
time ./speed_test.pl
real 0m14.713s
user 0m7.240s
sys 0m2.060s
#!/usr/bin/python3.2
fd = open('/var/logs/access.log', 'r')
host = {}
for line in fd:
ip, d = line.split(r':%%:', 1)
if ip not in host:
host[ip] = {}
#host[ip]['data'] = []
host[ip]['data'] = ''
#host[ip]['data'].append(d)
host[ip]['data'] = host[ip]['data'] + d
time ./speed_test.py
Traceback (most recent call last):
File "./speed_test.py", line 16, in
host[ip]['data'] = host[ip]['data'] + d
MemoryError
real 6m35.528s
user 3m13.940s
sys 3m19.828s
На 6-ой минуте переполнилась память...
Если использовать для хранения последующих строк список (раскомментить закоменченные строки), то переполнение памяти происходит значительно раньше:
time ./speed_test.py
Traceback (most recent call last):
File "./speed_test.py", line 7, in
for line in fd:
MemoryError
real 0m25.717s
user 0m7.016s
sys 0m2.168s
Не могу понять, почему питон показывает такие отвратительные результаты...