假设您想要计算剩余的下载时间,并且您有了所有需要的信息,即:文件大小、dl‘’ed大小、剩余大小、经过的时间、瞬时dl速度等。您如何计算剩余的dl时间?
当然,直接的方法是: size left /瞬间dl速度,或者:(time elapsed/dl‘’ed size)*size left。只是前者会受到瞬时速度偏差的影响,而后者不能很好地适应速度的变化。
一定有更聪明的方法来做到这一点,对吧?看看你目前用uTorrent下载的盗版软件和音乐。很容易注意到,它所做的不仅仅是前面提到的简单计算。实际上,我注意到有时当dl速度下降时,剩余的时间也会下降一段时间,直到它重新调整。
发布于 2009-04-28 16:36:41
嗯,正如你所说,使用绝对当前的下载速度不是一个很好的方法,因为它往往会波动。然而,像总体平均值这样的东西也不是一个好主意,因为那里可能也会有很大的波动。
考虑一下,如果我开始下载一个文件,同时下载其他9个文件。我只得到了正常速度的10%,但文件读到一半,其余9个完成了。现在我的下载速度是开始时的10倍。我最初10%的速度不应该是“还剩多少时间”的一个因素。再也不用计算了。
就我个人而言,我可能会取过去30秒左右的平均值,并使用它。这应该是基于最近的速度进行计算,而不是剧烈波动。30秒可能不是合适的数量,需要一些实验才能算出一个合适的数量。
另一种选择是设置某种“波动阈值”,在这种情况下,您不会进行任何重新计算,直到速度变化超过该阈值。例如(随机数,同样需要实验),您可以将阈值设置为10%。然后,如果您以100kb/s的速度下载,则在下载速度更改为低于90kb/s或110kb/s之前,不会重新计算剩余时间。如果发生其中一个更改,则会重新计算时间并设置新的阈值。
发布于 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或
<?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);输出
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发布于 2009-04-28 16:37:00
最明显的方法是介于两者之间,你需要一个下载速度的“移动平均值”。
https://stackoverflow.com/questions/798800
复制相似问题