views:

149

answers:

3

Sure you could divide the remaining file size by the current download speed, but if your download speed fluctuates (and it will), this doesn't produce a very nice result. What's a better algorithm for producing smoother countdowns?

+2  A: 

I think the best you can do is divide the remaining file size by the average download speed (downloaded so far divided with how long you've been downloading). This will fluctuate a little to start but will be more and more stable the longer you download.

Andreas Brinck
but consider the case where the user was downloading for the last 24 hours, and minutes ago the internet connection was just broken, and the user sees the download time not infinite. Is that a bug or a feature?
TiansHUo
The download time will tend to infinity if the connection remains broken.
Andreas Brinck
Yeah... I don't think I like this solution. It puts too much emphasis on download speeds hours ago. What particularly bothers me is that the first few seconds of download are usually pretty unstable as it ramps up (torrents connecting to more seeds) or slows down (Shaw's powerboost wears off), and thus I think should be discounted completely.
Mark
+4  A: 
speed=speedNow*0.5+speedLastHalfMinute*0.3+speedLastMinute*0.2
TiansHUo
i.e. weighted, putting emphasis on more recent time.
Mark
@mark, yeah you get it
TiansHUo
+1 this is hot!
Jas Panesar
+2  A: 

An exponential moving average is great for this. It provides a way to smooth your average so that each time you add a new sample the older samples become decreasingly important to the overall average. They are still considered, but their importance drops off exponentially--hence the name. And since it's a "moving" average, you only have to keep a single number around.

In the context of measuring download speed the formula would look like this:

averageSpeed = SMOOTHING_FACTOR * lastSpeed + (1-SMOOTHING_FACTOR) * averageSpeed;

SMOOTHING_FACTOR is a number between 0 and 1. The higher this number, the faster older samples are discarded. As you can see in the formula, when SMOOTHING_FACTOR is 1 you are simply using the value of your last observation. When SMOOTHING_FACTOR is 0 averageSpeed never changes. So, you want something in between, and usually a low value to get decent smoothing. I've found that 0.005 provides a pretty good smoothing value for an average download speed.

lastSpeed is the last measured download speed. You can get this value by running a timer every second or so to calculate how many bytes have downloaded since the last time you ran it.

averageSpeed is, obviously, the number that you want to use to calculate your estimated time remaining. Initialize this to the first lastSpeed measurement you get.

Ben Dolman
Simple, but looks good!
Mark