Ask Slashdot: Why Is It So Hard To Make An Accurate Progress Bar?
hyperorbiter writes "How come after 25 years in the tech industry, someone hasn't worked out how to make accurate progress bars? This migration I'm doing has sat on 'less than a minute' for over 30 minutes. I'm not an engineer; is it really that hard?"
Comment loading ...
Yes it is "that hard".
I did it all for the penguins!
Yes it is. And to be fair, it's a lot more accurate than Nostradamus ever was.
Things are asyncronous. You wait for things from disk, ram, user input, over the network etc. How long it will take is non-deterministic. So a task composed of a bunch of these little pieces will be non-deterministic too.
One reason is the progress bar starts out as just a generic tool to show that your loading hasn't froze. At first it is parsed correctly with the elements to be loaded, but as scope increases and more things load, it can get sketchy later on.
Another reason is it is difficult to estimate time left. If you look at some old FTP programs, they'd estimate the rest of the download's time based on how fast the previous has taken. Future lag, fragmented files, etc aren't taken into consideration.
There's a bunch more reasons, but namely the progress bar's main purpose is to show you that the whole system isn't locked up, which they've been doing well for the past 30 years or so.
God spoke to me
You know someone is going to take your suggestion literally as a tutorial on how to implement a progress bar - later they'll come back with some mystical crash always happening at 0%.
Patience is a virtue, but haste is my life.
See http://scribblethink.org/Work/kcsest.pdf and http://scribblethink.org/Work/Softestim/softestim.html
(No, I'm not being serious. The topic just reminded me of when I once jokingly justified a poorly estimated ETA on a "simple" development project by referencing the above paper.)
My favorite terrible progress bar was Internet Explorer, back in its early days of essentially being a renamed version of NCSA Mosaic. When attempting to load a site that wasn't available, the progress bar would slowly creep towards complete, despite the server being completely unresponsive. Then after a long while the browser would give up and stop the progress bar. Why on earth would the progress bar move if the server is completely unresponsive? Who programmed this? I would hope that they, like the inventor of Clippy, suffered a terrible death by fire.
Consider this: Once you've put progress on a bar, you can't take it off. Suppose you start a process that should take 20 minutes, and do the first 5 minutes, progress is now at 25%. But then, partway through, something unexpected happens and you realize the process is actually going to take 40 minutes. You can't take the progress "back" now, that would disorient the user. So you have to rescale the remainder of the bar.
Progress bars do not make sequences of actions complete any faster. In fact, they make them slower.
That being said, take for example an installer that must perform the following steps during an upgrade:
0. Figure out how many files need to be replaced.
1. Replace 30 files of varying sizes.
2. Add 10 files.
3. Update a half million rows inn a table with a million rows setting a column to a computed value based on some predicates.
4. Run a third party installation mechanism (MSM?) for a supporting library, etc.
Modern computers are time-sharing systems. Each process that involves computation is at the mercy of the scheduler in the kernel to give it the cycles it needs to complete. That means that even if you measure the time it takes to complete some process, it's not going to be the same a second time, because the installation process doesn't get undivided attention.
Steps 0 - 2 - you're at the mercy of the IO buses, hard disk, antivirus software interfering, etc.
Step 3 - What shape are the database statistics in? How efficiently can you apply the predicates? What does the distribution of the data look like? You can't tell this ahead of time...
Step 4 - Does this third party installer provide you some sort of metrics as it runs?
These are the sorts of problems to be overcome to do an accurate progress bar. In short, they aren't worth overcoming.
For over 50 years rocket launch countdowns have not run in a linear fashion, sometimes even being set backwards.
You can work out where you are (% completed) or how fast you are going (rate at which the progress bar is growing), but not both at the same time.
It's simple quantum mechanics.
I am anarch of all I survey.
I would have stopped at "yes" without the optimism, and it's not even a platform/processor issue. This is a fundamentally unsolvable thing, since in some cases it reduces to the halting problem. That best you can do is come up with an approximation.
But the approximations will be wrong too. Simple example: write speed. If you write a block to disk, and it fits into the operating system cache, a write happens almost instantly. If the cache is full, you might have to spend tens of seconds waiting before that write occurs. Here's what happens with installers, copy programs, and a large chunk of other things. You write until the cache fills, and those happen at memory speeds. Then, all of the sudden, you grind to a halt when the cache fills. You won't see any progress, sometimes for minutes--it can take a while to chug through gigabytes of random writes. I show an example of this on my blog on Linux, and this problem gets worse as memory increases, not better.
What does that look like to the user? They get a progress bar, it zooms along for a while, and then it cranks to a halt. Then it hangs for a bit, starts moving, and the whole thing completely changes scale. Does this sound familiar? That's what people complain about, right? You can't make that go away without building a model of the caching mechanism that's more accurate than the cache itself. After all, if you could predict this was coming, the OS could have done a better job scheduling I/O with that information, too. Think about that for a minute: to write a really good progress bar for write operations, you have to do a better job on I/O scheduling than Linux does.
If you step back and say "well let's approximate how long disk I/O takes then and base the bar on that", you'll discover that doesn't work either. There's over a 100:1 difference between the fastest and slowest storage on the market. Good luck modeling that accurately enough to predict the future, too.
The Windows8/Server 2012 dialog is much better in this case.
http://encosia.com/blog/wp-content/uploads/2012/09/windows-8-file-copy-dialog.png
It draws a graph showing you the current rate, in which you can see the average over time.
The progress bar on the HTTP download doesn't show the amount of remaining time in the bar. It shows the number of bytes remaining in the bar; the number of bytes remaining can't go into reverse. The time remaining is showed as a numeric value for how long it would take assuming the speed is the same as the speed so far; if the transfer suddenly slows down, this value can go into reverse.
It is hard to make an accurate progress bar because it shouldn't be a bar at all - it should be a graph.
Consider the humble download: bytewise, it might be 97 percent complete, but at the last moment, the bps rate has fallen. With a progress bar indicating a percentage and an estimated time, it might say 97% complete, 3 seconds to go. If the progress indicator was a graph, you could tell that the bps rate has fallen, and that the 3 seconds to go estimate (probably based on a linear extrapolation of progress to date) does not apply.
I have never seen it done though. Partly, because I have never done it.
The public opinion of the Progress Bar would be considerably more favorable if programmers would simply treat 100% as if it were 75%.
In other words, do all the stuff you have to do, measuring progress and whatnot, but when you're actually at 80%, report yourself at 60%. Likewise, when you're at 95%, say you're at 70%.
Then, only when you really are completely finished, you jump from 75% to 100% in under a second.
Complaints gone.
-David
You know what I'd like to see more than a working progress bar? A "Cancel" button that actually stops the f*%! process! .
I don't want to finish the sub-process I'm currently doing (which has probably stalled)... just FREAKING STOP.
If you (programmer) want to close connections, or save the changes to the disk, do it in the background. Making me sit there for another 10 minutes while you're "cancelling..." is not helpful. I will force close your program. Failing that I will hard-reset the computer. Seriously.
Unlike porn, which yada yada rimshot hey-ooh!
Give this man some upward moderation.
The problem is that the question is wrong. It's trivial to make a progress bar...just sum up all the things you have to do, and move the bar each time a "thing" is done, rounding to the nearest pixel. It doesn't matter if the "thing" is a byte to copy, a file to install, or any generic task. As long as you can add one to a counter each time you have done another "thing", you can then display it graphically.
The actual complaint is about displaying accurate time remaining to complete the task, which really has nothing to do with the display of the progress bar. Instead, it involves guessing about how long each remaining "thing" will take to complete, and then displaying that sum of those times. This is hard because no matter how accurate the data used to make the guess, something outside the control of the program can disrupt the processing.
No, wait. It seems to have stalled.
Have gnu, will travel.
Except even the number of tasks is often variable over the life of the task.
Take for example loading a web page. It starts out as 1 task: Get a page from the server. Once you've done that, how many more requests will that first request generate? Impossible to tell. It could be none. It could be hundreds, and some of those can generate their own requests. (etc, etc.)
The answer is this: Some feedback, no matter how incorrect, is better than no feedback at all.