Форум сайта python.su
173
SotericКстати, да. Нужно профилировать. Все очень просто:
Хорошо бы профилировщиком посмотреть на что тратится время, но я к сожалению не силен в профилировании питон приложений.
python -m cProfile -o profiler.dat your_application.py
pyprof2html profiler.dat
Офлайн
0
# -*- coding: utf-8 -*- import Queue import threading import httplib2 import time # для оценки скорости success = 0 time_start = time.time() def worker(): """ код потока """ global success global time_start h = httplib2.Http() h.timeout = 10 while True: time.sleep(0.01) try: u = q.get_nowait() (r, c) = h.request(u, "GET") success += 1 print("{0:.2f}".format(success/(time.time() - time_start))) except: pass # создать очередь q = Queue.Queue() # создать потоки for i in range(50): t = threading.Thread(target=worker) t.setDaemon(True) t.start() # внести задания в очередь file = open('u.txt', 'r') for i in file.readlines(): q.put(i.rstrip('\r\n')) file.close() # ждемс q.join()
Отредактировано DHT (Дек. 11, 2012 16:40:14)
Прикреплённый файлы:
u.txt (38,3 KБ)
Офлайн
20
time.sleep(0.01)
Отредактировано Soteric (Дек. 11, 2012 16:57:49)
Офлайн
0
SotericНа скорость работы существенно не влияет, а нагрузку на процессор снимает значительно.
зачем это?
# -*- coding: utf-8 -*- import Queue import threading import httplib2 import time # для оценки скорости success = 0 time_start = time.time() def worker(): """ код потока """ global success global time_start h = httplib2.Http() h.timeout = 10 while True: try: u = q.get() (r, c) = h.request(u, "GET") success += 1 q.task_done() print("{0:.2f}".format(success/(time.time() - time_start))) except: pass # создать очередь q = Queue.Queue() # создать потоки for i in range(50): t = threading.Thread(target=worker) t.setDaemon(True) t.start() # внести задания в очередь file = open('u.txt', 'r') for i in file.readlines(): q.put(i.rstrip('\r\n')) file.close() # ждемс q.join()
Отредактировано DHT (Дек. 11, 2012 17:11:21)
Офлайн
173
В данном случае (множество независимых серверов) скорость и оптимальное количество потоков зависит от канала.
Например, на домашнем ADSL 5Mbit
при 50 - еле дотягивает до 2 url/sec
при 15 - приближается к 4 url/sec
На сервере 100 Mbit
50 - 40-50 url/sec
100 - не дает особого прироста
Если действительно нужна скорость и есть хороший канал, смотрите в сторону асинхронных библиотек.
Вот код на grequests (под капотом greenlet, gevent, requests)
# -*- coding: utf-8 -*- import grequests import time SIMULTANEOUS = 200 started = time.time() with open('u.txt', 'r') as f: urls = f.read().splitlines() reqs = (grequests.get(url, timeout=10) for url in urls) for i, resp in enumerate(grequests.imap(reqs, size=SIMULTANEOUS)): if resp.ok: print("{0}/{1} {2:.2f}".format(i, len(urls), i/(time.time() - started))) # Можно делать что-то с resp.content или resp.text # Нужно учесть, что очередность при imap не соблюдается, # но есть resp.url А еще можно пользоваться hook'ами (колбэками)
Отредактировано reclosedev (Дек. 11, 2012 17:52:38)
Офлайн
0
reclosedevа что за сервер? просто у меня тоже 100 Mbit, но 40-50 не дает.
На сервере 100 Mbit50 - 40-50 url/sec
Офлайн
33
DHTПростое действие не дает простаивать потокам.
Если вместо запроса по HTTP сделать какое-нибудь простое дейтсвие, то потоки отрабатывают 10ки тысяч записей из очереди в секунду. Т.е. на реализацию работы с очередями я не жалуюсь. Жалусь лишь на httplib2.
Офлайн
173
DHTСамый дешевый VPS от Хетзнер с Ubuntu.
а что за сервер?
$ cat /proc/cpuinfo | grep MHz
cpu MHz : 3411.486
DHTЕсли подольше держать, тоже меньше числа показывает. Но это, возможно, из-за способа расчета.
40-50 не дает.
Офлайн
0
reclosedevВот-вот! На старте у меня тоже хорошая скорость, но потом замедляется и игра с таймаутами ничем не помогает.
Если подольше держать, тоже меньше числа показывает.
Офлайн
20
Можно собрать дополнительную статистику по времени выполнения запроса. Выделить максимальное время, за которое выполняется 99% запросов (или другое критичное значение). Установить значение реквест таймаута немного выше этой величины. Таким образом откровенно тормозные запросы не будут портить статистику. Потому что судя по “начало нормальное, а потом все тормозит” можно предположить, что со временем все больше и больше потоков оказываются вовлечены в парсинг очередного “тормозного” сайта. Плюс то, что сказал Lexander: в какой-то момент от увеличения потоков производительность начнет падать из-за того, что процессор будет проводить основную часть времени на переключении между потоками.
Отредактировано Soteric (Дек. 12, 2012 09:37:07)
Офлайн