2016-07-25 4 views
0

Я думаю, что requests.get должен быть блочным, поэтому не должно быть разницы между run и run2.Почему gevent может ускорить загрузку запросов?

import sys 

import gevent 
import requests 
from gevent import monkey 
monkey.patch_all() 
def download(): 
    requests.get('http://www.baidu.com').status_code 
def run(): 
    ls = [gevent.spawn(download) for i in range(100)] 
    gevent.joinall(ls) 
def run2(): 
    for i in range(100): 
     download() 
if __name__ == '__main__': 
    from timeit import Timer 
    t = Timer(stmt="run();", setup="from __main__ import run") 
    print('good', t.timeit(3)) 
    t = Timer(stmt="run2();", setup="from __main__ import run2") 
    print('bad', t.timeit(3)) 
    sys.exit(0) 

но результат:

good 5.006664161000117 
bad 29.077525214999696 

так есть все виды чтения, записи могут быть ускорить путем GEvent?

PS: Я запустить его на Mac/Python3/запросов 2.10.0/GEvent 1.1.2

+0

Я не слишком знаком с 'gevent', но я предполагаю, что это связано с I/O. Когда вы делаете веб-запрос, есть накладные расходы на установление соединения с сервером, принятие рукопожатия и т. Д. Многие из них заканчиваются простоями, в течение которых клиент ждет ответа. Хотя он простаивает, 'gevent' скорее всего отправляет другие запросы. Однако реализация Python-only будет ждать завершения каждого запроса перед отправкой другого. –

+0

, которые имеют смысл, поэтому r'equests.get' не блокируется все время, часть его задания заменяется gevent, который может делать что-то еще, если блок. Дело в том, насколько 'gevent' может изменить' запросы', например, он может изменить почти все 'urllib'.so, что намного быстрее запросов. –

ответ

-1

gevent website Из:

Быстрый цикл обработки событий на основе libev (Epoll на Linux, Kqueue на FreeBSD).

Легкие исполнительные устройства на основе greenlet.

API, который повторно использует концепции из стандартной библиотеки Python (например, существуют gevent.event.Events и gevent.queue.Queues).

кооперативные гнезда с SSL поддержкой

DNS запросов осуществляется через ThreadPool или с-аров.

обезьяна латания утилита для получения 3-го модулей сторонних стать кооперативным

В принципе, просто for зацикливания кучи requests.get() вызовов медленно из-за того, что ты, ну, for перекручиванием через кучу requests.get() звонки. Gevent'ing куча requests.get() звонков не замедляется из-за того, что вы выбрасываете эти вызовы в поточную очередь, а затем использует мощный API-интерфейс gevent для эффективного выполнения этих вызовов.

+1

ru, я знаю, что вы имеете в виду. Но вы не отправляете эти вызовы в поточную очередь, а не ', что ничего не меняет, если задание является блоком, одно время выполняет одно задание, а работа -« спать, чтобы ждать »!! ! никто не двигается, пока он не будет выполнен. –

+0

В вашем примере блокировка фактически не влияет на что-либо. Вы только 'request.get()' ing. В самом деле. Таким образом, Thread 'Queue' срабатывает так много таких заданий, как gevent/ваш процессор. Теперь, если у вас было такое изменение переменной (скажем, строковое значение на основе текста страницы), блокирование, безусловно, вступит в игру из-за GIL. – crashfocus

 Смежные вопросы

  • Нет связанных вопросов^_^