python请求的理想块大小

use*_*335 23 python performance python-requests

选择块大小有什么指导方针吗?

我尝试了不同的块大小,但它们都没有提供与浏览器或wget下载速度相当的下载速度

这是我的代码的快照

 r = requests.get(url, headers = headers,stream=True)
 total_length = int(r.headers.get('content-length'))
 if not total_length is None: # no content length header
 for chunk in r.iter_content(1024):
     f.write(chunk)
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.?

编辑:我尝试了不同速度的网络..而且我能够实现比我的家庭网络更高的速度..但是当我测试wget和浏览器时..速度仍然无法比较

谢谢

And*_*ter 10

您将失去在读取和写入之间切换的时间,并且块大小的限制仅为AFAIK可以存储在内存中的限制.因此,只要您不太关心保持内存使用率,请继续并指定大块大小,例如1 MB(例如1024 * 1024)甚至10 MB.1024字节范围内的块大小(甚至更小,因为它听起来你测试了更小的尺寸)将大大减慢过程.

对于一个非常繁重的情况,你希望从你的代码中获得尽可能多的性能,你可以看看io模块的缓冲等.但我认为将块大小增加1000或10000左右可能会让你大部分的方式.


小智 9

可能为时已晚......但问题在于您如何请求对象(文件)。您使用的是非持久 http 连接,这意味着对于每个文件,您会产生 2 个往返时间 + 文件的传输时间。这基本上意味着每个文件需要增加两次 ping 时间。假设平均 ping 为 330 毫秒,那么每个文件的平均 ping 时间为 660 毫秒。如果只有 10 个文件,这已经大约需要 6-8 秒。解决方案是使用会话,它为您的所有请求建立持久的 http 连接。此外,使用 raise_for_status() 方法比检查内容是否为空更容易

import requests
session = requests.Session()
r =session.get(url, headers = headers, stream = true)
r.raise_for_status()
for chunk in r.iter_content(1024):
     f.write(chunk)
Run Code Online (Sandbox Code Playgroud)

  • 在写这篇文章时这可能是真的,但我不再相信这是真的了。在最新的 pypi 版本中 `requests.get` 自动创建一个会话:https://github.com/psf/requests/blob/72eccc8dd8b7c272e520f22b0256386c80864e94/src/requests/api.py#L59C27-L59C27 (2认同)

Mar*_*cin 2

根据您的代码,问题很可能是您没有使用缓冲 IO。如果这样做,那么每次 write 调用应该非常短(因为它是缓冲和线程化的),并且您可以从线路中获取相当大的块(3-10Mb)。

  • 我不是反对者,但我不认为缓冲 IO 是必要的,以便从线路中获取大块。如果有的话,相反的情况可能更正确——如果没有缓冲 IO,那么获取大块会更重要。缓冲 IO 可能会略微提高性能,但我认为 OP 的问题比缓冲 IO 与非缓冲 IO 更大;即块大小本身。 (2认同)
  • @AndrewGorcester你已经得到了这个倒退:使用无缓冲IO意味着应用程序在单个线程中的读取和写入之间切换。 (2认同)