【问题标题】:Why is Python's requests 10x faster than C's libcurl?为什么 Python 的请求比 C 的 libcurl 快 10 倍?
【发布时间】:2021-09-13 09:15:14
【问题描述】:

对于 1.6 MB 的请求(requests 需要 800 毫秒,而 curl/libcurl 有时需要 7 秒)。

  • 这是为什么?

  • 如何让 C 中的 curl 与 Python 中的 requests 一样快?

libcurl 似乎以 16KB 块的形式得到它的回复,而 requests 似乎一次得到了整个东西,但我不确定是不是这样......我试过 curl_easy_setopt(curl_get, CURLOPT_BUFFERSIZE, 1<<19) 但它似乎只是使缓冲区大小更小

我尝试查看requestssource code,我认为它使用urllib3 作为其HTTP“后端”...但直接使用urllib3 会导致与使用 curl 的结果相同(令人失望)。

这里有一些例子。

/*
gcc-8 test.c -o test -lcurl  &&  t ./test
*/
#include <curl/curl.h>

int main(){
  CURLcode curl_st;
  curl_global_init(CURL_GLOBAL_ALL);

  CURL* curl_get = curl_easy_init();
  curl_easy_setopt(curl_get, CURLOPT_URL,           "https://api.binance.com/api/v3/exchangeInfo");
  curl_easy_setopt(curl_get, CURLOPT_BUFFERSIZE, 1<<19);
  curl_st=curl_easy_perform(curl_get);  if(curl_st!=CURLE_OK) printf("\x1b[91mFAIL  \x1b[37m%s\x1b[0m\n", curl_easy_strerror(curl_st));

  curl_easy_cleanup(curl_get);
  curl_global_cleanup();
}
'''FAST'''
import requests
reply = requests.get('https://api.binance.com/api/v3/exchangeInfo')
print(reply.text)
'''SLOW'''
import urllib3
pool = urllib3.PoolManager()  # conn = pool.connection_from_url('https://api.binance.com/api/v3/exchangeInfo')
reply = pool.request('GET', 'https://api.binance.com/api/v3/exchangeInfo')
print(reply.data)
print(len(reply.data))
'''SLOW!'''
import urllib.request
with urllib.request.urlopen('https://api.binance.com/api/v3/exchangeInfo') as response:
  html = response.read()
'''SLOW!'''
import pycurl
from io import BytesIO
buf  = BytesIO()
curl = pycurl.Curl()
curl.setopt(curl.URL, 'https://api.binance.com/api/v3/exchangeInfo')
curl.setopt(curl.WRITEDATA, buf)
curl.perform()
curl.close()
body = buf.getvalue()  # Body is a byte string. We have to know the encoding in order to print it to a text file such as standard output.
print(body.decode('iso-8859-1'))
curl https://api.binance.com/api/v3/exchangeInfo

【问题讨论】:

  • 了解您如何对这些示例进行基准测试会很有用,以便我们比较结果。对我来说,libcurl 的运行速度最快,比 requests 快一个数量级,这与我的预期差不多。所以也许包括一些你如何运行示例和时间的细节?
  • 也许你在使用 libcurl 时没有启用 gzip encoding。通过 HTTP 发送未压缩文件可能需要更长的时间。
  • 我可以确认@r3mainer 点。如果没有CURLOPT_ACCEPT_ENCODING,C 程序确实比 (fixed!) Python 脚本慢得多。添加CURLOPT_ACCEPT_ENCODING将使C程序比Python脚本更快。
  • @r3mainer 成功了。谢谢!现在 curl 在 500-700 毫秒内运行。
  • @r3mainer:您应该将其添加为答案...

标签: python c curl https libcurl


【解决方案1】:

加快网络内容传输的一种方法是使用HTTP compression。这是通过在服务器和客户端之间发送数据之前动态压缩数据来实现的,因此传输时间更短。

虽然HTTP compression is supported by libcurl,但默认是禁用的:。来自CURLOPT_ACCEPT_ENCODING 文档:

将 CURLOPT_ACCEPT_ENCODING 设置为 NULL 以显式禁用它,这 使 libcurl 不发送 Accept-Encoding: 标头并且不解压缩 自动接收内容。

这个参数的默认值为NULL,所以除非你专门开启HTTP压缩,否则你不会得到它。

【讨论】:

    猜你喜欢
    • 2016-07-07
    • 2018-08-12
    • 2023-03-03
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2014-07-13
    • 2017-02-03
    • 1970-01-01
    相关资源
    最近更新 更多