You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python编写仿wget工具时计算MB/s下载速率的公式是否正确?

下载速率统计逻辑评估与优化方案

你当前的逻辑是计算从下载启动到当前时刻的整体平均下载速率,这个逻辑本身没有计算错误,在带宽稳定的场景下和实际速度匹配度很高,问题主要在场景适配性上:

  • 短时间网络波动的时候,平均速率的变化会很滞后,没法实时反馈当前的实际下载速度
  • 如果下载的文件很小,总下载耗时不足1秒的话,time.time()-old的差值太小,会导致计算出来的速率数值误差极大

无需更换网络的多带宽验证方法

你不用换物理网络环境也能做不同带宽的验证:

  • Linux 环境可以直接用 tc 命令限制网卡带宽,比如执行 tc qdisc add dev eth0 root tbf rate 1mbit burst 10k latency 70ms 就能把网卡限速到1Mbps,测试完用 tc qdisc del dev eth0 root 恢复即可
  • Windows 环境可以用系统组策略或者第三方限速工具给程序限制带宽,也能模拟不同网络环境

优化实现方案

推荐用滑动窗口统计最近N秒的平均速率,兼顾实时性和平滑性,比全周期平均的显示效果更符合用户感知:

import time
from collections import deque

print(f"Downloading: [{size/1048576:.2f}MB]{file_name}...")
done = 0
old = time.time()
# 初始化滑动窗口,保存最近1秒内的(时间戳, 下载字节数)记录
speed_window = deque()
WINDOW_SECONDS = 1  # 窗口大小,数值越大速率显示越平滑,越小越灵敏

for chunk in r.iter_content(chunk_size=65536):
    f.write(chunk)
    chunk_len = len(chunk)
    done += chunk_len
    now = time.time()
    
    # 更新滑动窗口,移除过期记录
    speed_window.append((now, chunk_len))
    while speed_window and now - speed_window[0][0] > WINDOW_SECONDS:
        speed_window.popleft()
    
    # 计算速率,窗口数据不足时 fallback 到总平均
    if len(speed_window) >= 1 and now - speed_window[0][0] > 0:
        window_total = sum(i[1] for i in speed_window)
        window_time = now - speed_window[0][0]
        mbps = f"{window_total / window_time / 1048576:.2f}"
    else:
        total_time = max(now - old, 0.1)
        mbps = f"{done / total_time / 1048576:.2f}"
    
    perc = done / size
    progress_bar = "=" * int(perc * 50) + " " * (50 - int(perc * 50))
    print(f"[{progress_bar}][{mbps}Mb/s]{int(perc*100)}%", end="\r")
f.close()

优化点说明

  • 滑动窗口统计的速率更接近用户感知的「当前网速」,不会被前期的速度拉低/拉高显示值
  • 替换了原来的字符串切片取前4位的写法,用格式化字符串保留2位小数,避免出现10.2、102.这类异常显示格式
  • 加了除零保护,避免刚开始下载时间差过小的时候计算报错

内容的提问来源于stack exchange,提问作者Topster_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:36:03