![](/img/trans.png)
[英]get http raw (unparsed) response in http.client or python-requests
[英]Why is Python 3 http.client so much faster than python-requests?
我今天正在測試不同的Python HTTP庫,我意識到http.client
庫的執行速度比requests
快得多。
要測試它,您可以運行以下兩個代碼示例。
import http.client
conn = http.client.HTTPConnection("localhost", port=8000)
for i in range(1000):
conn.request("GET", "/")
r1 = conn.getresponse()
body = r1.read()
print(r1.status)
conn.close()
這里是與python-requests做同樣事情的代碼:
import requests
with requests.Session() as session:
for i in range(1000):
r = session.get("http://localhost:8000")
print(r.status_code)
如果我啟動SimpleHTTPServer:
> python -m http.server
並運行上面的代碼示例(我正在使用Python 3.5.2)。 我得到以下結果:
http.client:
0.35user 0.10system 0:00.71elapsed 64%CPU
蟒蛇,請求:
1.76user 0.10system 0:02.17elapsed 85%CPU
我的測量和測試是否正確? 你也可以復制它們嗎? 如果有,是否有人知道http.client
內部發生了http.client
,使它更快? 為什么處理時間有這么大的差異?
基於兩者的分析,主要區別似乎是requests
版本正在為每個請求執行DNS查找,而http.client
版本只執行一次。
# http.client
ncalls tottime percall cumtime percall filename:lineno(function)
1974 0.541 0.000 0.541 0.000 {method 'recv_into' of '_socket.socket' objects}
1000 0.020 0.000 0.045 0.000 feedparser.py:470(_parse_headers)
13000 0.015 0.000 0.563 0.000 {method 'readline' of '_io.BufferedReader' objects}
...
# requests
ncalls tottime percall cumtime percall filename:lineno(function)
1481 0.827 0.001 0.827 0.001 {method 'recv_into' of '_socket.socket' objects}
1000 0.377 0.000 0.382 0.000 {built-in method _socket.gethostbyname}
1000 0.123 0.000 0.123 0.000 {built-in method _scproxy._get_proxy_settings}
1000 0.111 0.000 0.111 0.000 {built-in method _scproxy._get_proxies}
92000 0.068 0.000 0.284 0.000 _collections_abc.py:675(__iter__)
...
您將主機名提供給http.client.HTTPConnection()
一次,因此有意義的是它會調用gethostbyname
一次。 requests.Session
可能會緩存主機名查找,但顯然不會。
編輯:經過一些進一步的研究,這不僅僅是一個簡單的緩存問題。 有一個函數可以確定是否繞過最終調用gethostbyname
代理,無論實際請求本身如何。
來自@Lukasa的復制粘貼回復發布在這里 :
請求較慢的原因是因為它比httplib實際上更多。 httplib可以被認為是堆棧的底層:它執行套接字的低級爭用。 請求是兩層,並添加了諸如cookie,連接池,其他設置和各種有趣的東西之類的東西。 這必然會減慢速度。 我們只需要計算比httplib更多的東西。
您可以通過查看請求的cProfile結果來看到這一點:結果比httplib的結果更多。 高級庫總是會出現這種情況:它們會增加更多開銷,因為它們需要做更多的工作。
雖然我們可以看一下目標性能改進,但在所有情況下,調用堆棧的絕對高度都會嚴重損害我們的性能。 這意味着“請求比httplib慢”的抱怨總是如此:它就像抱怨“請求比在套接字上發送精心設計的原始字節要慢”。 這是真的,而且永遠都是真的:我們無能為力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.