雖然顯示在窗口中的下載狀態,我有如下信息:算法中的一個穩定的「下載剩餘時間」的下載窗口
1)總文件大小(F)
2)下載的文件大小(F ')
3)當前的下載速度(S)
甲幼稚剩餘時間的計算將是(F-F')/(S),但該值的方式,TO-搖搖欲墜(剩餘6m /剩餘2h /剩餘5m!deja vu ?! :)
會有一個既穩定又不極端錯誤的計算(即使下載即將完成時顯示1h)?
雖然顯示在窗口中的下載狀態,我有如下信息:算法中的一個穩定的「下載剩餘時間」的下載窗口
1)總文件大小(F)
2)下載的文件大小(F ')
3)當前的下載速度(S)
甲幼稚剩餘時間的計算將是(F-F')/(S),但該值的方式,TO-搖搖欲墜(剩餘6m /剩餘2h /剩餘5m!deja vu ?! :)
會有一個既穩定又不極端錯誤的計算(即使下載即將完成時顯示1h)?
我們通過以下方式解決了類似的問題。我們對下載速度超過整個時間的速度感興趣,根據最近的活動大概需要多長時間,但正如您所說,不是那麼近以至於數字會跳到各處。
我們對整個時間段不感興趣的原因是,下載可能會在一個半小時內達到1M/s,然後在接下來的十分鐘內切換到10M/s。儘管事實上你現在正在以相當快的速度振奮人心,但上半個小時將會嚴重拖慢平均速度。
我們創建了一個循環緩衝區,每個單元格在1秒內保存下載量。循環緩衝區大小爲300,允許5分鐘的歷史數據,並且每個單元初始化爲零。我們還保留了總數(緩衝區中所有條目的總和,所以最初爲零)和計數(顯然爲零)。
每一秒,我們會想出多少數據已經自最後一秒鐘,然後下載:
基本上,在僞代碼:
def init (sz):
buffer = new int[sz]
for i = 0 to sz - 1:
buffer[i] = 0
total = 0
count = 0
index = 0
maxsz = sz
def update (kbps):
total = total - buffer[index] + kbps
buffer[index] = kbps
index = (index + 1) % maxsz
if count < maxsz:
count = count + 1
return total/count
你可以改變你的分辨率(1秒)和歷史(300),以滿足您的情況,但我們發現,5分鐘內餘長,以至於它平息了違規行爲,但仍然逐步適應了更加持久的變化。
平滑s(exponential moving avg。或類似)。
謝謝!看起來像一個好地方開始。 – Abhishek 2009-11-24 06:53:21
這實際上就是低通濾波器。 – 2009-11-24 15:13:58
爲什麼不計算下載速度的平均值在整個下載的,那就是:
s = f'/elapsed time
這樣,能夠順利地隨着時間的推移。
想到你下載了50%的100kb/s的一小時長的下載。然後你開始另一個下載並且速度下降50kb/s你的下載時間指示器將是錯誤的,直到你的下載結束。它會說30分鐘,而顯然將需要我們下載其餘的。 – 2009-11-24 06:54:20
其實,你無法預測第二次下載需要多長時間。第二次下載可能總共爲50KB。在這種情況下,你會在整個8秒內顯示1小時,然後回覆到30分鐘。預測是困難的,尤其是當涉及到未來:P – MSalters 2009-12-02 10:26:36
我更喜歡在最後10秒內使用平均速度,並用剩下的部分進行劃分。如果將當前速度劃分爲整體進度的平均值而不太穩定,則無法處理永久速度變化(如另一次下載正在開始)。
我不相信平滑的平均會削減它;我觀看了我的Ubuntu更新下載了一半價值的文件,並且我注意到了一個非常明確的模式 - 較大文件的平均速度比較小文件的平均速度要快得多(高達5倍甚至10倍)。如果你對使用的協議做了假設(例如ftp,http),那麼你應該能夠推斷出爲什麼會發生這種變化(注意由於涉及的所有細節都不容易,但也不是不可能)。基本上,隨着時間的推移,我會嘗試改進預測下載速度和時間作爲大小函數的函數。 – 2010-11-06 17:38:42