83% of Advent Remaining
Sufficiently Advanced (ProgressBar) Technology
At YAPC::NA 2004 in Buffalo, Damian Conway gave a talk on "Sufficiently Advanced Technologies," in which he showed off a number of very simple interfaces for fairly complex operations. Among the libraries he talked about was Smart::Comments, a source filter that turns comments into code. It had a bunch of functions, but one of them let you do this:
...and your program would, on one line, cycle through stuff like this:
Analyzing [| ] 0% done Analyzing [===| ] 25% done Analyzing [========| ] 50% done Analyzing [============| ] 75% done Analyzing [=================] 100% done
Progress bars are hard to get right! Just look at any implementation you've seen in otherwise great, well-designed software, like Microsoft Windows. They often provide progress bars that jump between "almost done" and "-919 days remain."
Smart::Comments can have this problem, too, as the workload changes out from under it -- some items in
@input, for example, might be costly to analyze, for example. There might be
next statements, or
lasts, all of which can interfere with proper job speed detection.
Acme::ProgressBar is always accurate. No matter what the characteristics of the input are, no matter how the loop flow is altered, no matter what, Acme::ProgressBar is accurate. Only extreme system load or fatal signals can interfere with its accuracy.
It's very easy to use, too. It isn't a source filter, and uses no complex features. It should never introduce bugs to your code and can be added or removed to your code easily. Written with Acme::ProgressBar instead, the above code would look like this:
...and would produce output like this (but all on one line, and I've omitted some lines for brevity's sake):
Progress: [ ] (calculating time remaining) Progress: [== ] 8s remaining Progress: [==== ] 6s remaining Progress: [====== ] 4s remaining Progress: [======== ] 2s remaining Progress: [==========] 0s remaining
There can be a performance cost for using Acme::ProgressBar, but the impact varies from program to program. You should test it in your code before judging the performance costs.
The source code for Acme::ProgressBar may also be instructive.