Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 10, 2013 13:05:56

aborodin
Зарегистрирован: 2013-10-10
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Медленный парсинг файла

Всем привет.
Есть текстовый файл, в каждой строка
число;строка;ip-адрес;число
Всего 9600 строк. Я выбираю только ip-адреса следующим образом

    for text in file.readlines():
        text = text.rstrip()
        regex = re.findall(';[0-2]?[0-9][0-9]?.[0-2]?[0-9][0-9]?.[0-2]?[0-9][0-9]?.[0-2]?[0-9][0-9]?;', text)
        if regex is not None and regex not in ips:
            ips.append(regex)
Этот кусок выполняется 7 секунд, мне кажется это медленно. Посоветуйте что сделать чтобы ускорить выполнение скрипта. Спасибо.

Офлайн

#2 Окт. 10, 2013 13:25:31

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Медленный парсинг файла

вынеси из цикла создание регулярки

Офлайн

#3 Окт. 10, 2013 13:35:05

aborodin
Зарегистрирован: 2013-10-10
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Медленный парсинг файла

сделал так

    regex_ = re.compile(';[0-2]?[0-9][0-9]?.[0-2]?[0-9][0-9]?.[0-2]?[0-9][0-9]?.[0-2]?[0-9][0-9]?;')
    for text in file.readlines():
        text = text.rstrip()
        regex = re.findall(regex_, text)
        if regex is not None and regex not in ips:
            ips.append(regex)
    print(time.time()-ts)
все равно 7.279864072799683 сек

Офлайн

#4 Окт. 10, 2013 13:51:42

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Медленный парсинг файла

if regex is not None and regex not in ips:
Одна проверка явно лишняя
if not regex in ips:

И еще, in это дорогая операция, если ips список и если он большой. Если нельзя обойтись без этой проверки, то сделайте ips множеством.

l = range(10000)
s = set(range(10000))
def list_test():
	return 5088 in l
def set_test():
	return 5088 in s
if __name__ == '__main__':
	import timeit
	print(timeit.timeit("list_test()", setup="from __main__ import l, list_test", number=1000))
	print(timeit.timeit("set_test()", setup="from __main__ import s, set_test", number=1000 ))
результаты
0.0621750354767
0.000143051147461



Офлайн

#5 Окт. 10, 2013 13:55:33

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Медленный парсинг файла

Зачем regex, если известен разделитель полей?

tuple(text.rstrip().split(";"))
даст тот же результат, но быстрее.

В остальном я бы мыслил так:

1. Какая версия Питона (есть разница между readlines, for line in f:)?
2. Сколько занимает чистый readlines (нужно локализовать место тормозов)?
3. Какой размер файла? Может его проще весь в память загнать с помощью f.read() ?



Офлайн

#6 Окт. 10, 2013 13:57:26

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Медленный парсинг файла

вызывай метод на созданном объекте регулярки

Офлайн

#7 Окт. 10, 2013 14:00:31

aborodin
Зарегистрирован: 2013-10-10
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Медленный парсинг файла

FishHook, я попробую как осмыслю чем это может обернуться.

Lexander, есть не нулевая вероятность что может появиться “лишний” разделитель в текстовом поле
1. python 3.2
3. 832350 байт

Офлайн

#8 Окт. 10, 2013 14:02:42

masterito
От:
Зарегистрирован: 2011-06-13
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Медленный парсинг файла

Небольшая оптимизация использования памяти:
file.readlines() - читает все строки в list.

For reading lines from a file, you can loop over the file object. This is memory efficient, fast, and leads to simple code:
>>> for line in f:
        print line,



Офлайн

#9 Окт. 10, 2013 15:43:55

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Медленный парсинг файла

re.findall возвращает список, эти вычисления:

regex not in ips:
            ips.append(regex)
будут на порядок тяжелей. Используй re.search с, как уже заметили, множеством.

text = text.rstrip()
наверное, не нужно
еще regex я бы все-таки назвал по-другому

Офлайн

#10 Окт. 10, 2013 15:53:12

fttk
Зарегистрирован: 2012-08-13
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Медленный парсинг файла

Раз айпишники все равно уникальные, можно хранить в словаре, там гораздо быстрее лукапы делаются. Плюс непонятно зачем регулярка. Допустим вы не можете сделать сплит, потому что во второй колонке могут встречаться точки с запятой, тогда можно сделать индекс с конца.

Как-то так:

ips = {}
for line in f.readlines():
    ips[line.split(';')[-2]] = None
ips = ips.keys()

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version