Thursday, April 15, 2010

Why you should get a high end PC - RAM

This is part 2. Part 1 is here.

RAM is good. The more RAM the better.

RAM is so important that most of the time we just call it memory. There's lots of different types of memory attached to modern computers. There's hard disk, flash, buffer and cache memories to choose from. The thing is, when you just say “memory” and don't bother to qualify it, you mean RAM. That's how important it is. It doesn't even need the word “the” in front. It's implicit. That's how friggin' important it is.

The main benefits of having more memory is that allows you to use applications that manipulate huge chunks of data all at once.. Programs like this include games, photo editing applications, video editing applications and medical imaging viewers.

Generally you don't need to make the decision to buy more RAM. The applications you're using will do it for you. Essentially, one day you'll see a new, shiny application available for download that you just have to have. You'll download the application, try to run it and and suddenly realize you need more memory.



Windows 7 is the first consumer 64-bit OS from Microsoft that you'd actually want to run and unlike windows XP, it's not limited to 2 (ish) gigs of memory. Expect software developers to take advantage of the new memory situation by making their apps take up more memory (or should I say, "make their apps do something cool". No. No, I shouldn't.)

Curiously, modern operating systems don't just give up or complain when they run out of memory. Instead they will simply cram as much into memory as possible and stick the rest in the pretender-to-the-throne-memory – hard disk. In this case, you know you've run out of memory when your hard drive starts going bonkers and your PC slows down to a crawl. If you're not saving something or loading something your hard drive shouldn't be doing anything. If it is, you may need more memory.

Having more RAM than you need for the applications you run can also speed up the computer. If you have more RAM available than your computer is actually using, the machine will allocate the extra RAM to a disk cache. This is good because it means that even when you're loading something, it won't read it from the hard disk it will just use the copy already in memory. As a result, it loads incredibly fast. In my first article about storage I mentioned that before my solid state drive I used to get more RAM than I really needed. The disk cache is why. If you're too cheap to get an SSD at least max out your system memory. A run of the mill 7200RPM consumer grade hard drive will see huge gains. With a laptop's slow 4200RPM hard disk it's even more important.

(Cute girls know your laptop needs more RAM)

Note that caches work by keeping a copy of the data in memory after it's been read the first time from a hard disk. PCs often read the same things off the hard drive repeatedly due to the way programmers build their applications. The net result of this is that having a disk cache can make a surprising number of things faster.

One last thing, make sure you get your RAM from a reputable brand. Cheap, no name memory may seem like a good deal but there are quite a few bad RAM chips out there. Bad RAM can be a huge pain to diagnose since it just shows up as random crashing - which could be symptoms of almost any problem. A few good brands are Corsair, Kensington and OCZ. There are others..

So, in conclusion: RAM is good. The more RAM the better.

.. and, might I add: get more.

Next up: monitors. Why only having one is so old school.


Part 1

Sunday, April 11, 2010

Why you should get a high end PC - storage

I've noticed a recent article that said that Apple has a 90% share in the computer is over a thousand dollars category. I think this is rather sad.

I don't think it's sad that Apple is doing well, this is actually quite nice. What I find sad is that people aren't buying PCs over a thousand dollars. There are some excellent reasons why you'd want a PCs over a thousand dollars.

Let's start with the hard drive. Most PCs come with a relatively small hard drive. This is silly because coming with a small hard drive means you're actually paying a lot per megabyte. It also means your PCs that run very slowly because smaller hard drives have a smaller information density which means the drive has to spin faster to achieve the same data transfer rates. Every generation there's an optimum price point for megabytes per dollar. It's not that expensive either. Last time I check this optimal point was for hard drives costing about 100$. Getting a hard drive outside this range is just throwing money away in my opinion because you always need more hard drive space.

Hard drives are otherwise my mortal enemy. Hard drives have gotten tremendously large but they haven't gotten that much faster. While the transfer rate of the drive tends to be proportional to the size of the drive the access time is proportional to the rotation rate, the speed the head can move and physical size platter size of the drive. These factors haven't really changed. The rotational speed has only gone from 4200RPM to 7200RPM but the drive size has gone from 20 MB to being 1 TB in size. That's 1 000 000 MBs! Every time the system has to retrieve a byte from the hard disk it has to wait an eternity. I hate the stupid things! I've even gone so far as to add much more RAM to my system than usual to have a huge disk cache so my machine doesn't need to access the hard disk. Have you considered a solid state drive recently?

I've recently bought an OCZ Vertex solid-state drive for use with Windows 7 on my machine and it is completely awesome. To put the speed difference in perspective consider this: good hard drives have access times of around 18 milliseconds. Good solid-state drives have an access time of about an 0.18 of a millisecond. That's a hundred times faster. Additionally, they can have transfer rates of over 200 MB a second. Hard drives have a transfer rate of 50 MB a second. In practice the performance is extremely noticeable. I'll say it again, they are super awesome.

They only downside to a solid state drive is that it doesn't hold a great deal of data for the price. My OCZ Vertex cost around 400$ and only holds 120 GB. This isn't as much of a problem as you might think though because you just have to put all your data – music, video other data, on a standard hard drive and use your SSD for windows, the swap file and most of the applications. Your system will still fly and you can store all the data you want. I recommend getting a drive slightly bigger then you think you'll need. Getting too much space is a bit embarrassing, getting too little space is a time consuming disaster.

If you've bought a netbook with a solid-state drive and haven't really been impressed by the performance we're not really talking about the same things here.

(The difference in speed amongst SSDs is huge. It's worth reading up on why that is and which drives are really worth buying.)

The technology has come along way since those early drives. The software has also been improved. Windows XP will fight with a solid-state drive but Windows 7 includes optimizations to maximize the performance you get out of the drive. This means you don't have problems like, for example, the performance of the solid-state drive degrade over time. Modern drives also don't freeze the entire computer whenever you write lots of pieces of data to them at the same time. Early and current netbooks sometimes use out of date drive controllers that still have this problem.


Another thing that useful on the higher end PC is more memory. But I'll talk about that next time.

Part 2

Thursday, April 8, 2010

Space Smilies - a technological demonstration in one lvl

In 1999 I was first introduced to Java. I quite liked it. It was the first language that I'd come across in which it was possible to write your own draw routines while simultaneously being comprehensible. Sure, I already knew C and to a lesser extent C++ but to me it had always seemed like doing anything in those languages was incredibly painful. In Java it was relatively easy. The best thing about Java, though, was its runtime and draw routines were fast enough to write a small video game in. That March break I decided to write a video game. I called it Space Smilies after the placeholder smiley face icons I was using at the time.

Ever since then I've occasionally revisited code to see if I can figure out, using my newly acquired X years of experience, why somethings never quite worked right. I also spent some time to try and take advantage of the new abilities of the latest Java virtual machine (not to mention the processor power of the newest machines). I've just completed my latest batch of fixes and enhancements and am ready to release them to the world. Let me give you a rundown of what's been enhanced recently.

First off, I've corrected all those dang threading bugs. While I understood what threads were I wrote the original application I didn't really understand all the different ways in which you can screw up using threads. Since then I've learned a great deal about threads and, in fact, have become quite familiar with them. As a result of this, the newest version of Space Smilies draws the back buffer to the component on the event thread. It used to draw back buffer to the component on the thread I was using for the game engine. This doesn't really work well because AWT and swing aren't thread safe.


I'm also using a sort of triple buffering. The game engine draws to a back buffer. This back buffer is then given to the event thread on a sort of back buffer queue. The event thread then takes the latest back buffer and draws it to the component. After drawing to the component the back buffer is put into a free pool. When the game engine needs a new back buffer for the next frame, it looks in the free pool to see if one is available. The upshot of all this is that the final blitting is done on a different thread than the game engine which is doing the compositing.

Additionally, I'm using volatile buffers wherever possible to let the video card do most of the blitting and compositing. For whatever reason I can't get bit masked volatile buffers to be accelerated. This means that the bulk of the compositing is done on the CPU although the star-field (which is the biggest blob of pixels by far) is composited all on the video card.

(This is all on windows, your millage may vary on other operating systems)

Finally, I got the resolution of the game up from postage stamp sized to 1000 x 700. The old game used to remain fixed at that resolution but the new game will scale itself to take up as much area on the screen as it can.

I'm quite interested to know whether it works for everyone. You'll need Java 6 though. With any luck you actually have that but don't know it. Try it out either way.

Monday, March 22, 2010

Is it a bug or a feature?

If you do development for long enough large enough team you will find yourself asking this question. It matters because you need to make decisions about what gets fixed in the current release and what only gets fixed in the next release. In other words, what should be part of version 1.0.1 and what should in version 2.0. Additionally, there is also a school of thought which says that bugs should always be fixed before new features are added. Which is great, but this assumes you actually know what a bug is.

So what is a bug and how does it differ from a feature?

What is a bug depends on who you talk to. To a developer, a bug is a mistake. To tell a developer that there is a bug in their code is to tell the developer that he be screwed up. This can lead to all sorts of unfortunate confusion between end users, QA and the developer. In reality no one (except possibly the developer) actually cares whether or not it's a particular individual's a mistake. What people care about is whether or not the program is working in a way that makes sense. For example, if an application gets out of large knife and stabs the user in the eye when they select "Copy" from the "Edit" menu it doesn't really matter if the developer intentionally programmed it to do that. What matters is the behavior is undesirable. Well, I presume the behavior is undesirable. You might actually be trying to create an application that stabs the user in the eye whenever they select Copy from the Edit menu. I don't presume to know what crazy project you're actually working on.

QA, for instance, will tend to think of any stupid behavior as a bug. For example, let's say that QA files a bug that the font sizes too small to be readable. The developer takes a look at what font size should be, double checks to see that he's using the right size and then simply claim that it's not a bug. Presumably he then goes on to stab QA in the eye.

Sale and marketing are even more out there. They have no idea how anything actually works and as a result can consider six man years worth of work to be a bug. For example, if the email client you're building doesn't do SMTP autentication then that's a bug. It's a bug because it doesn't work with this particular SMTP server. I mean come on! What were you thinking?

At Intelerad, we've gotten fed up with discussions on whether something is a bug or a feature and started thinking about everything as change requests. Once you're looking at everything as a bunch of change requests you can start focusing on the things that actually matter about those change requests and use that criteria to make decisions.

What are we trying to encapsulate when we ask if something is a bug or feature? It may matter because you made a policy that says that bugs can get fixed on existing branches or releases would features will always be fixed along the trunk. Okay, but why did you make the decision that only bugs get fixed along batches? Did you make the assumption that bugs would simply be things that were easy and quick to fix? If that's the case then why don't you say that only change requests that are easy and quick to fix get fixed along branches. Did you make the assumption that bugs would be severe; that they would stop the user from being able to use some feature of the application? If that's the case then why don't you say that only change requests that affect critical functionality will get fixed along branches. Did you make the assumption that feature work would be too destabilizing along the stable branch? If that's the case then why don't you say that only change requests that are not destabilizing will get fixed along branches. Don't say that he will only fix bugs be precise about which aspects of the change requests will allow you to fix an issue along an existing branch.

Here are the things we typically consider:

How bad is the problem?
Would the fix destabilize the old version?
How long does it take to fix?

The first two questions are the most important. The last question is more of a sanity check. If the answer to the last question is anything more than about a day, then you're probably lying to yourself about it not destabilizing anything. It should also go on the trunk because it represents significant development.

I'm making the assumption that you've already discovered that you should be working along the trunk by default. Ideally you shouldn't be back porting anything. You should be releasing major versions often enough that your clients (or users) can wait until the next major version. If they can't wait until the next version you're not releasing often enough. That's pretty much a golden rule. The length of your release cycles should be matched with the expectations and demands of your client base.

Thursday, June 11, 2009

The speed size and dependability of a reddit traffic spike

Humm.. It looks like my blog posting on progress bars has taken off on reddit. I actually posted the article to reddit after a friend's blog posting had hit the big time on that site as well. although it didn't work.. yeah..

He had just written a blog posting comparing the speed, size and dependability of almost all programming languages using a novel graphing technique. He is a computer languages guy and ever since reading tufte he's been into using graphs to represent data in new and enlightening ways. I thought the blog posting was impressive. Apparently somebody else did too and posted it to reddit. From there it took on a life of its own and found its way to multiple sites including the venerable Slashdot.

I've always loved how that happens. I used to write a peer-to-peer application called Myster. When introducing Myster to the world, we didn't do much advertising. The only thing we did was to post it to one or two Macintosh oriented websites. One of which was the venerable MacInTouch. Oh wow. I woke up the morning that it was posted to a set of crashed computers. Apparently my p2p network wasn't as scalable as I thought.

After frantically fixing the accidental thread bomb (and about a dozen scalability issues for which the application's new found fame turned out to be very useful) I started to track where Myster was being mentioned. The answer, it turned out, was everywhere. It was showing up on news sites I'd never heard of. It was in application repositories I'd never added it to. Myster had been available for about a year and had never really gotten anywhere. Then, one morning we posted it to the right place and it explodes.

I quickly realized that in order to have any control over how my application was going to be presented I needed to move quickly or else somebody would do it for me. This, being an important task, was delegated to a neighbor of mine who turned out to be very good at it. :-) He is now a bike courier. Completely wasted talent if you ask me. He did the website for Myster as well is all the graphics. Just look at the logo. It's gorgeous! I mean argh! irk! egh! Anyway, enough of that.



The speed that news travels on the Internet is impressive. It's scary how fast you can go from "Oh, someone has posted my article on reddit " to "Oh crap, how much is all this bandwidth going to cost me?".

My friend had gotten his page to the financial-panic level of Internet popularity and I was curious to know if I could do the same with my article on progress bars. So, I dutifully signed up for a brand, spanking new account on reddit and tried submitting my article. It didn't get much love.

Actually, it didn't get any love. It got exactly zero votes. This was not the reception I was hoping for but I figured it was probably just the content. I mean who would want to read a 5000 ish word article on the intricacies of progress bars anyway?

My friend said I was completely wrong.

In his opinion my reddit submission title completely sucked. He was sure he could do better. No, that doesn't accurately reflect his scorn for my reddit abilities. He was sure he could do better with one hand tied behind his back and a family of monkeys beating his head with old IBM clickety keyboards. But first he had to wait a few days because reddit doesn't like duplicate submissions...

Well, today he took a stab at it and last time I checked it was top of the heap.. so I guess he's right. I have my doubts as to whether the monkeys were using real, genuine, old-school IBM clickety keyboards but I must admit it's still impressive.

Just for the record, I'm also still glad I delegated Myster's PR fanfare to that neighbor-friend of mine. Perhaps he should start a blog? I'd read it and I promise not to submit it to reddit. :-)

Sunday, May 31, 2009

How to work with progress bars, part 2

On the last episode of "As Andrew Rambles About Progress Bars" (or whatever I'm calling this series) I raised the following questions:

What if, you have a task for which it is completely impossible to gauge how long the task will take?

What if, you have a task for which you have a rough estimate for how long it will take but, you have no way to increment the progress bar because the library/process/whatever doesn't provide any feedback. For example, maybe you're running a third-party process and there's no way for you to get any feedback about what that process is doing. Now would you do?

What if there's a bomb on a bus. Once the bus goes 50 miles an hour, the bomb is armed. If it drops below 50, it blows up. What do you do? What do you do?

I have answers to these questions. Well, all questions except the last one. But first: task estimation.

In the comments of my last article, a friend of mine pointed out that I never actually mentioned how you come up with the numbers you pass to compositeProgressBar.buildSubProgressBar(). Typically, all you need to do is run your program a few times and time how long each sub task takes. You can then figure out how long the task is spending in each one of the subtasks. You then use that to figure out what to send to compositeProgressBar.buildSubProgressBar().

For example:


sub task | time in seconds | value to send to compositeProgressBar.buildSubProgressBar()
1 | 10 | 10 / 45 = 0.222
2 | 20 | 20 / 45 = 0.444
3 | 15 | 15 / 45 = 0.333

Total time: 45 seconds


And there you go. I would suggest doing more than one timing with many sets of data.

Sometimes the ratios don't stay fixed and instead vary depending on what sort of machine you're running on or what set of data you have.

The programmers I've talked to are always concerned about giving inaccurate information in a progress bar. They've all experienced the frustration of an inaccurate progress bar. It's important to not fall into the trap of thinking that the progress bar needs to be super accurate. At the same time, you need to be careful you don't make the classic error of having a progress bar that jumps to 90% done right away and stays there forever. It can be a delicate balancing act but in my experience, programmers often underestimate the value and accuracy of the information they have.

Consider the following: as a programmer, you almost always know approximately how long the task will take to complete to complete. Put yourself in the user's shoes. The user has absolutely no clue whatsoever how long the task will take to complete. As far as the user is concerned it can take a second, an hour, a day or a millions years. If you know the task will take, at most, one minute, then you already know far more than your user. Communicate this very valuable information to them.

Before we continue remember that there is no solution to determining how long a task will take in the general case. To solve that you would need to solve the the halting problem. That's not going to happen. Instead I can show you a few tricks I've learned about displaying a progress bar in circumstances where you wouldn't think it would be possible.

First question: what is the probability that the task will finish at any given time?



If the probability graph looks like this:



That's good. It's an easy candidate for progress bar because the progress bar tends to finish in one range of values of time.

If you have a task made up of subtasks, it's also makes things easy if the time taken by each sub task stays in a fixed ratio. That is, if one sub task takes 1 second then you know that the next sub task will take approximately 1.5 seconds and the sub task after that will always be a little shorter. In this case, let's say half a second.

If each of the subtasks doesn't stay in a fixed ratio than that's a bummer. When estimating the time a task will take, it's good to consider whether it's likely your task is network bound, disk bound, CPU bound or other. This is important because if you have a large task that consists of, say, a network bound task and a CPU bound task then it's going to be difficult to give an accurate (at least with respect to time) progress bar. On one computer, you may have a very fast CPU with a very slow network connection and on another computer the situation may be reversed. This will cause the progress bar to zip through one section of the meta- task and then crawl through the other section.



The situation above are fairly rare. Most tasks tend to use some combination of the resources of a machine and as a result the differences in the speed of various components tend to cancel out so that the ratios between the different subtasks tend to remain constant (to some reasonable approximation).

If you have run your progress bar a few times and are not happy with its accuracy you have two choices. 1) Run a calibration loop or otherwise figure out how to compensate for these things on that particular machine or 2) live with the fact your progress bar isn't going to be super accurate.

There's something of a black art to writing calibration loops. You have to be careful of things like caches and you have to make sure that you add the right fudge factors to make the progress bar behave correctly. It's surprisingly time-consuming to do this right and most times, in my experience anyway, it's not worth the effort. If you find yourself having to do one of these then it is going to take you a while.

A more common problem is that a program might have no way of getting any feedback as to the progress of one of its subtasks. This can happen if you have to hand off a task to a library.

If you actually do know, approximately, how long that task will take to complete in real time then you still have a chance. You may know that it will take approximately 2 seconds for every item that it's processing. Or you may be able to guess at how long the task will take given the time it took to complete some previous processing step. For example, if it took 5 seconds to complete the first step, it should only take about 10 seconds to complete the second step.

In these situations I like to use a technique that I call Zeno's progress bar. It's a way of providing a progress bar when you have no idea what the real progress is. It's terrifyingly convincing.

Before I continue I would just like to say that I am serious when I say it's terrifyingly convincing. I've actually been duped by my own Zeno's progress bar at least once.

While using the product I work on (Inteleviewer) one day, I noticed that it was providing a progress bar. However, I was under the impression that this was impossible because the task it was using a library that had no way of providing any feedback. I was curious to see if someone on the team had fixed the library or had found some other clever trick to get the library to provide feedback. Someone had found a trick. It was me! It was my own Zeno's progress bar! I had made this error knowing that there were these sorts of progress bars lurking in the code. It was then I knew I had to share this idea with the world.

I came up with the idea based on watching how people would provide their time estimates for tasks that they weren't being informed on the progress of but had some idea of how long it should take.

An example would be an online merchant that knows that something is supposed to ship within two weeks but since it's being shipped by the manufacturer of the product, they really have no good idea of the order's real status. They will tell you it will ship in two weeks and if it doesn't then they will tell you it will ship next week and if it doesn't then they will tell you will ship in the next few days. It still hasn't shipped they will always keep repeating that it will ship in the next few days. Only at this point you start to realize that it may never ship at all.

If you think about it you can probably come up with other examples of this sort.

The technique works really well when your estimate is off slightly. It works even better when your estimate is dead on. This is what it looks like in a progress bar:



Let's say you have a task that could take 10 seconds. You start off with the progress bar moving at a speed that is consistent with the task taking 10 seconds. At the 5 second mark you slow the speed of the progress bar by half. So that by the 10 second mark the progress bar will only be at 75% complete. If all goes well, and your estimate of 10 seconds is correct, then the progress bar will just jump to 100% at this point. If it doesn't and your task is going to take longer then you slow the speed of the progress bar by half again. By the 15 second mark the progress bar will now be at 87.5% complete. This goes on until your task completes.

Obviously, you should try to avoid giving overly optimistic estimates. Being completely off results of one of those annoying 99% complete progress bar that we all love to hate. Being off by only a factor of two, however, actually still gives a half decent effect.

Okay, so how do you code this puppy?

Well, the first step is to create an object to update the progress bar without any help from the task itself. You see, usually the task would tell the progress bar to update from its own thread. In this case it won't so we'll have to reproduce the effect using a timer. It looks like this:



/**
* Makes a progress bar that can show progress if all you know is approximately
* how long the task will take.
*/
public class MagicProgressBar {
private static double BASE = 0.5;

private final Progress progress;
private final int estimatedTime;
private final Timer timer;

private long startTime;

public MagicProgressBar(Progress progressBar, int estimatedTimeOfTask) {
this.progress = progressBar;
this.estimatedTime = estimatedTimeOfTask;
timer = new Timer(30, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//progress.advance( magic??? );
}
});
}

public void start() {
startTime = System.currentTimeMillis();
timer.start();
}

public void stop() {
timer.stop();
}
}


You would use it like this:


private static void doMagic(Progress masterProgress) {
MagicProgressBar magicBar = new MagicProgressBar(masterProgress, TIME_ESTIMATE);

magicBar.start();
doStuff(); // doesn't provide progress
magicBar.stop();

masterProgress.advance(1);
}


Where "doStuff()" is the task were waiting to complete. Note that TIME_ESTIMATE is not usually a constant. In many cases it would be calculated by using a weighting number, like we sent to compositeProgressBar.buildSubProgressBar(), and the time it's taken to do some earlier step in the task.

Well, we still need to add the implementation of the timer in the MagicProgressBar class. Let's do that now.


timer = new Timer(30, new ActionListener() {
public void actionPerformed(ActionEvent e) {
long timeSinceStart = System.currentTimeMillis() - startTime;
int unitLengthInMillis = estimatedTime / 2;
int units = (int) (timeSinceStart / unitLengthInMillis);

double percent = ( timeSinceStart % unitLengthInMillis ) / (double) unitLengthInMillis;
progress.advance(findSum(units) + percent * Math.pow(BASE, units + 1) );
}
});

private static double findSum(int n) {
return (Math.pow(BASE, n + 1) - BASE) / (BASE - 1);
}


"findSum()" is calculating how far complete the progress bar should be given at a given time unit index. In our example, where we expect the task to take 10 seconds, unit index 1 would be the first 5 seconds, unit 2 would be the next 5 seconds, unit 3 would be the 5 seconds after that etc... a unit's length is equal to one half of the estimated time of the task.

The rest of the code is either trying to figure out which time unit we're at or how far through the current time unit we are.

Let's see what the object looks like when we put it all together:


/**
* Makes a progress bar that can show progress if all you know is approximately
* how long the task will take.
*/
public class MagicProgressBar {
private static double BASE = 0.5;

private final Progress progress;
private final int estimatedTime;
private final Timer timer;

private long startTime;

public MagicProgressBar(Progress progressBar, int estimatedTimeOfTask) {
this.progress = progressBar;
this.estimatedTime = estimatedTimeOfTask;
timer = new Timer(30, new ActionListener() {
public void actionPerformed(ActionEvent e) {
long timeSinceStart = System.currentTimeMillis() - startTime;
int unitLengthInMillis = estimatedTime / 2;
int units = (int) (timeSinceStart / unitLengthInMillis);

double percent = ( timeSinceStart % unitLengthInMillis ) / (double) unitLengthInMillis;
progress.advance(findSum(units) + percent * Math.pow(BASE, units + 1) );
}
});
}

public void start() {
startTime = System.currentTimeMillis();
timer.start();
}

public void stop() {
timer.stop();
}

private static double findSu5m(int n) {
return (Math.pow(BASE, n + 1) - BASE) / (BASE - 1);
}
}


Now you have the power of Zeno's progress bar. Use it wisely, young grasshopper. Zeno's progress bar has no mind. Isn't it wiser to seek proper progress reporting then to desire the swift completion of the programming exercise? Oops, I'm channeling David Carradine again. All I'm trying to say is don't use it for the hell of it. That's all.

Okay, on to the next part which is all about indeterminate progress bars.

This is what an indeterminate progress bar looks like:



The one of the left is used on the Macintosh. The one on the right is used by Windows.

Indeterminate progress bars are used to signal that we have absolutely no idea how long a task is going to take. Both the Macintosh and Windows version of this type of progress bar use animation to signal that, yes, there really is something happening. The computer has not fallen asleep. It has not started daydreaming. It hasn't quit and joined a hippie commune where it's not asked to do tasks that are difficult to estimate tasks all day.

If you really, really don't know how long the task is going to take then this is the progress bar to use.

The decision to use an indeterminate progress bar is a hard one. Most of the time you'll want to avoid using it. Users don't like being in the dark about how long their computer might be occupied. Going back to my online merchant example above, this would be the equivalent of an indeterminate progress bar:

Customer: How long is it going to take the ship?
Merchant: I don't know.
Customer: Is it going to take about two weeks? Or two days? Or two years?
Merchant: I don't know.
Customer: Are you saying it may take two years for me to get my package?
Merchant: It could. I don't think that's very likely though. Well, I don't know, it could take two years. Yes. Maybe.

Despite the fact that indeterminate progress bars are annoyingly, I can think of two common uses for them..

The first use is for the relatively short-lived progress bar that shows up because the computer is taking a little longer than it should to do something and the programmer thought that he should provide some obvious feedback that the computer hasn't crashed. These indeterminate progress bars are often short-lived. Most the time the programmers didn't even think it would be shown at all. I haven't seen one of these types of progress bars in a while. In this case the indeterminate progress bar means "hang on a second".

Another common use for the indeterminate progress bar when it's used at the beginning of a long task when the computer is still calculating how long it will take for it to do the task. For example, if you're running a calibration loop at the beginning of your process, you might show an indeterminate progress. Another example would be the OS might show an indeterminate progress when it's calculating the number of files involved in a file copy operation. It's also often used at the beginning of a task when trying to connect to a remote server. Connecting to a remote server is one of these things that will either be instantaneous or take a while due to the server being down or a network error.

In these examples you go from an indeterminate progress bar to a regular progress bar. This sort of transition is okay. You're essentially saying to the user "I have no idea how long this is going to take" because you're trying to figure out how long the task is going to take. So long as this step is relatively short it's ok.

Going from a regular progress bar to an indeterminate progress bar is less ok. It's like saying you know how long a task is going to take then saying you have no idea then claiming you know again.



I have seen this behavior when it's used to mean "hang on a second, I've got an unexpected delay". A task might display this when it tries to connect to a server that's taking a while to respond. I've also seen it during a compression task that would occasionally start an optimization step. If the optimization step was taking too long the progress bar would become indeterminate for a while.

Progress bars that go from a determinant progress to an indeterminate and back are very rare. It's probably not a pattern you'll ever need to use.

Well, that's all I have to say. If you want to read more about progress bars (and who doesn't.. pfff..) then I'd suggest visiting Jeff Atwood's blog post on the subject. It's a great starting off point. He also goes into how to make your task look like it ran faster without actually making the task run any faster.

You can also check out the miscellaneous human interface guidelines documents by Microsoft and Apple. Perhaps you want to expand your horizons into other kinds of progress indicators.

Oh, and here's the source code for all the examples I've given.

Until next time bye.

Thursday, May 28, 2009

Cross Canada Bike Trip

Well, my parents have officially left for their cross canada bike tour. The tour is to raise money for the JDRF. They are making a blog of their trip. They will posting as they find wi-fi spots. I wish them luck.