2016-07-25 23 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造成的。當您發出Web請求時,與服務器建立連接,進行握手等等的開銷會很大。很多情況會導致客戶端等待響應的空閒時間結束。當它閒置時,'gevent'很可能會發出其他請求。不過,僅Python實現會在發送另一個請求之前等待每個請求完成。 –

+0

這是有道理的,所以r'equests.get'不會阻止所有的時間,他的工作的一部分被gevent取代,如果阻塞,它可以做其他事情。 關鍵是'gevent'可以改變'requests',例如,他可以改變幾乎所有'urllib'.so,這比請求要快得多。 –

回答

-1

gevent website

基於libev(在Linux的epoll,kqueue的快速上事件循環FreeBSD的)。

基於greenlet的輕量級執行單元。

API重用Python標準庫中的概念(例如gevent.event.Events和gevent.queue.Queues)。

支持SSL

DNS查詢合作插孔通過線程池或c-頃進行。

猴子修補程序來獲得第三方模塊成爲合作

基本上,只要for循環一堆requests.get()電話較慢,由於這樣的事實,你,好了,for通過一堆循環requests.get()來電。由於您將這些調用放入線程化隊列中,然後使用gevent的強大API非常高效地運行這些調用,所以調用一堆requests.get()調用的速度並不慢。

+1

en,我知道你的意思。但是你把這些調用放到一個線程隊列中,如果工作被阻塞,一次​​做一項工作,而工作是「睡覺等待」,則不會改變任何東西! !沒有人會動,直到他完成了工作。 –

+0

在你的例子中,阻塞實際上並不影響任何東西。你只是'requests.get()'。真。所以,線程'隊列'就像gevent /你的處理器允許的那樣多的工作。 現在,如果你修改了一個變量(比如說基於頁面文本的字符串值),那麼由於GIL,阻塞肯定會在那裏發揮作用。 – crashfocus

相關問題