【问题标题】:Ideal Chunk Size for python requestspython请求的理想块大小
【发布时间】:2014-04-29 15:57:38
【问题描述】:

是否有选择块大小的指南?

我尝试了不同的块大小,但没有一个能提供与浏览器或 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)

任何帮助将不胜感激。?

编辑:我尝试了不同速度的网络..而且我能够达到比我的家庭网络更高的速度..但是当我测试 wget 和浏览器..速度仍然没有可比性

谢谢

【问题讨论】:

  • 你下载的资源有多大?
  • 大约 3-10 MB 左右
  • 你尝试了多大的块?
  • 我尝试了 1024 的倍数...即.... 1,2,3,4,8,16,256,512...谢谢
  • @user3570335 那么,你找到合适的块大小了吗?

标签: python performance python-requests


【解决方案1】:

可能为时已晚...但问题在于您如何请求对象(文件)。您正在使用非持久 http 连接,这意味着对于每个文件,您会产生 2 次往返行程 + 文件的传输时间。这基本上意味着每个文件需要增加两个 ping 时间。平均 ping 为 330 毫秒,即每个文件为 660 毫秒。只有十个文件,这已经是大约 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)

【讨论】:

    【解决方案2】:

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

    对于您希望从代码中获得尽可能多的性能的非常繁重的情况,您可以查看 io 模块以进行缓冲等。但我认为将块大小增加 1000 倍或者 10000 左右可能会让你大部分时间到达那里。

    【讨论】:

    • 正如我提到的,我尝试到 512*1024 仍然没有提高速度。所以我猜它与请求模块或读取的窗口优先级有关。因为我使用了 youtube-dl 一个用 python 编写的程序。而且速度要高得多——注意它是编译程序
    • 哦,我看错了。我以为你已经尝试过 1, 2, 3, 4 而不是 1024 * 这些数字。嗯,在那种情况下我不确定。我会首先将一个巨大的块(比如 10 MB 或更大)读取到内存中的临时文件,然后查看该速度的比较;如果可行,则将其写入磁盘并比较结果。
    • 切换时间不是问题。
    • 速度 - 代码 --> 400-500 kb , wget 等大约 1 -1.2 MB
    • 嗯,这是一个非常大的差距。如果块大小适当大,那么我不相信这或缺乏缓冲 IO 是问题所在。
    【解决方案3】:

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

    【讨论】:

    • 我不是反对者,但我不认为缓冲 IO 是必要的,以便从线路中获取大块。如果有的话,相反的情况可能更正确——如果你没有缓冲 IO,那么获取大块更重要。缓冲 IO 可能会在一定程度上提高性能,但我认为 OP 比缓冲 IO 与非缓冲 IO 存在更大的问题;即块大小本身。
    • @AndrewGorcester 你倒退了:使用无缓冲 IO 意味着应用程序在单个线程中在读取和写入之间切换。
    • 我理解那部分!我认为在这种情况下大块大小很有用的原因是代码只会在读取和写入之间切换几次而不是数万次,并且磁盘访问将是一次长写入而不是多次小写入。在写入之前将一个非常大的块加载到内存中实际上是缓冲到内存;写入不会是并发的,但至少会是全速的,来自内存中的数据,并且上下文切换最少。
    • @AndrewGorcester 好吧,不。问题不在于切换。这是他们串联的事实。在这种情况下,可能从远程连接读取需要很长时间;事实上,它可能需要比写更长的时间。从根本上说,使用同步 IO 会影响此应用程序的性能。
    【解决方案4】:

    你可以改变块大小的条件如下

    ~/apps/erpnext/htdocs/frappe-bench/sites/assets/js$ vi desk.min.js
    

    第一步:

    chunk_size = _ref$chunk_size === undefined ? 24576 : _ref$chunk_size, Line 
    no:2078
    

    根据需要增加

    chunk_size = _ref$chunk_size === undefined ? 2457600 : _ref$chunk_size,
    

    第二步:-

    var file_not_big_enough = fileobj.size <= 24576; Line no: 8993
    

    根据需要增加喜欢

    var file_not_big_enough = fileobj.size <= 2457600; 
    

    【讨论】:

    • 语言错误@NarendraSharma。该问题标有python,用python编写,标题中包含“python”。
    猜你喜欢
    • 1970-01-01
    • 2017-01-18
    • 2013-03-30
    • 2018-11-27
    • 1970-01-01
    • 2021-09-19
    • 2010-12-04
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多