首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算剩余下载时间的最佳方法是什么?

计算剩余下载时间的最佳方法是什么?
EN

Stack Overflow用户
提问于 2009-04-28 16:33:14
回答 7查看 10K关注 0票数 15

假设您想要计算剩余的下载时间,并且您有了所有需要的信息,即:文件大小、dl‘’ed大小、剩余大小、经过的时间、瞬时dl速度等。您如何计算剩余的dl时间?

当然,直接的方法是: size left /瞬间dl速度,或者:(time elapsed/dl‘’ed size)*size left。只是前者会受到瞬时速度偏差的影响,而后者不能很好地适应速度的变化。

一定有更聪明的方法来做到这一点,对吧?看看你目前用uTorrent下载的盗版软件和音乐。很容易注意到,它所做的不仅仅是前面提到的简单计算。实际上,我注意到有时当dl速度下降时,剩余的时间也会下降一段时间,直到它重新调整。

EN

回答 7

Stack Overflow用户

发布于 2009-04-28 16:36:41

嗯,正如你所说,使用绝对当前的下载速度不是一个很好的方法,因为它往往会波动。然而,像总体平均值这样的东西也不是一个好主意,因为那里可能也会有很大的波动。

考虑一下,如果我开始下载一个文件,同时下载其他9个文件。我只得到了正常速度的10%,但文件读到一半,其余9个完成了。现在我的下载速度是开始时的10倍。我最初10%的速度不应该是“还剩多少时间”的一个因素。再也不用计算了。

就我个人而言,我可能会取过去30秒左右的平均值,并使用它。这应该是基于最近的速度进行计算,而不是剧烈波动。30秒可能不是合适的数量,需要一些实验才能算出一个合适的数量。

另一种选择是设置某种“波动阈值”,在这种情况下,您不会进行任何重新计算,直到速度变化超过该阈值。例如(随机数,同样需要实验),您可以将阈值设置为10%。然后,如果您以100kb/s的速度下载,则在下载速度更改为低于90kb/s或110kb/s之前,不会重新计算剩余时间。如果发生其中一个更改,则会重新计算时间并设置新的阈值。

票数 12
EN

Stack Overflow用户

发布于 2009-04-28 17:37:01

您可以使用平均算法,其中旧值呈线性衰减。如果S_n是时间n的速度,A_{ n-1 }是时间n-1的平均值,则按如下方式定义您的平均速度。

A_1 = S_1

A_2 = (S_1 + S_2)/2

A_n = S_n/(n-1) + A_{n-1}(1-1/(n-1))

在英语中,这意味着在过去的测量中发生的时间越长,它就越不重要,因为它的重要性已经衰减。

将其与普通平均算法进行比较: A_n = S_n/n + A_{n-1}(1-1/n)

你也可以让它以几何方式衰减,这将使最近的速度变得非常重要: A_n = S_n/2 + A_{n-1}/2

如果速度是4,3,5,6,那么A_4 = 4.5 (简单平均值)

A_4 = 4.75 (线性衰减)

A_4 = 5.125 (几何衰减)

PHP中的示例

注意,由于的数组是零索引的,所以 $n**)是当前数据点的数量,而不是 $n+1 。要匹配上面的示例,请设置** n == $n+1 n-1 == $n

代码语言:javascript
复制
<?php

$s = [4,3,5,6];

// average
$a = [];
for ($n = 0; $n < count($s); ++$n)
{
    if ($n == 0)
        $a[$n] = $s[$n];
    else
    {
        // $n+1 = number of data points so far
        $weight = 1/($n+1);

        $a[$n] = $s[$n] * $weight + $a[$n-1] * (1 - $weight);
    }
}

var_dump($a);


// linear decay
$a = [];
for ($n = 0; $n < count($s); ++$n)
{
    if ($n == 0)
        $a[$n] = $s[$n];

    elseif ($n == 1)
        $a[$n] = ($s[$n] + $s[$n-1]) / 2;

    else
    {
        // $n = number of data points so far - 1
        $weight = 1/($n);

        $a[$n] = $s[$n] * $weight + $a[$n-1] * (1 - $weight);
    }
}

var_dump($a);


// geometric decay
$a = [];
for ($n = 0; $n < count($s); ++$n)
{
    if ($n == 0)
        $a[$n] = $s[$n];
    else
    {
        $weight = 1/2;

        $a[$n] = $s[$n] * $weight + $a[$n-1] * (1 - $weight);
    }
}

var_dump($a);

输出

代码语言:javascript
复制
array (size=4)
  0 => int 4
  1 => float 3.5
  2 => float 4
  3 => float 4.5

array (size=4)
  0 => int 4
  1 => float 3.5
  2 => float 4.25
  3 => float 4.8333333333333

array (size=4)
  0 => int 4
  1 => float 3.5
  2 => float 4.25
  3 => float 5.125
票数 11
EN

Stack Overflow用户

发布于 2009-04-28 16:37:00

最明显的方法是介于两者之间,你需要一个下载速度的“移动平均值”。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/798800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档