Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Python's requests 10x faster than C's libcurl?

Python's requests library seems to be ~10x faster than C's libcurl (the C API, the CLI application, and the Python API) for a 1.6 MB request (requests takes 800ms, while curl/libcurl sometimes takes as much as 7 seconds).

  • Why is this?

  • How can I get curl in C to run as fast as requests in Python?

libcurl seems to be getting its replies in 16KB chunks, while requests seems to get the whole thing at once, but I'm not sure this is it... I tried curl_easy_setopt(curl_get, CURLOPT_BUFFERSIZE, 1<<19) but it only seems good to get the buffer size to be smaller.

I've tried looking at the source code for requests, and I think it uses urllib3 as its HTTP "backend"... but using urllib3 directly results in the same (disappointing) results as using curl.

Here are some examples.

/*
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
like image 585
étale-cohomology Avatar asked Jul 01 '21 09:07

étale-cohomology


People also ask

Is Libcurl fast?

The results leaves no room for doubts: the libcurl-based version is significantly faster than the “native” alternatives. The PHP binding for libcurl, PHP/CURL, is a popular one.

Why is PycURL fast?

PycURL is extremely fast (it is known to be much faster than Requests, which is a Python library for HTTP requests), has multiprotocol support, and also contains sockets for supporting network operations.

Is PycURL faster than requests?

Speed - libcurl is very fast and PycURL, being a thin wrapper above libcurl, is very fast as well. PycURL was benchmarked to be several times faster than Requests. Features including multiple protocol support, SSL, authentication and proxy options.

Does Python request use curl?

In Python, cURL transfers requests and data to and from servers using PycURL. PycURL functions as an interface for the libcURL library within Python. Almost every programming language can use REST APIs to access an endpoint hosted on a web server.


1 Answers

One way of speeding up the transfer of web content is to use HTTP compression. This works by compressing data on the fly before it is sent between the server and client so it takes less time to transmit.

Although HTTP compression is supported by libcurl, it is disabled by default:. From the CURLOPT_ACCEPT_ENCODING documentation:

Set CURLOPT_ACCEPT_ENCODING to NULL to explicitly disable it, which makes libcurl not send an Accept-Encoding: header and not decompress received contents automatically.

The default value of this parameter is NULL, so unless you specifically enable HTTP compression, you won't get it.

like image 165
r3mainer Avatar answered Oct 20 '22 14:10

r3mainer