2008-01-20
Layering buffering on top of other buffering is usually a bad idea
Here's something that I've seen illustrated more than once: layering buffering on top of buffering is almost always a bad idea.
One of the reasons is that it can be tricky to write a correct version. For example, consider all the things that you have to get right if you write a file IO buffering layer on Unix, including:
- you must remember that you've seen an EOF, and return this indication
to the next level up without doing another underlying
read(). - you must return short reads, unless you're explicitly doing forced buffering.
(If you do forced buffering, you need your own code to handle record oriented reading, including line at a time; otherwise you will be unusable for things like network protocols.)
It can also be hard to understand the performance implications of multiple levels of buffering. A related problem is that another level of buffering can accidentally cover up terrible performance in your own code, simply because it usually doesn't get run enough for you to notice. (I'm not talking about unoptimized code; I'm talking about code that has catastrophically bad performance if tickled the right way.)
Does this mean that Unix's standard IO library is a bad idea, since the kernel already does buffering? No, for two reasons. First, the kernel doesn't guarantee that it will keep those buffers around, so your IO might not be buffered after all. Second, standard IO also 'buffers' system calls, which lets it turn what would otherwise be very expensive operations into cheap ones.
(For example, reading only a single line without buffering means that you need to read each character separately. That would be a lot of system calls.)
2008-01-03
Scrolling versus panning
In thinking more about my dislike of smooth scrolling, I think it's useful to distinguish scrolling through something from panning through it. The difference is that panning operations are a continuous process, whereas scrolling is a discrete thing that theoretically has a specific size that it's supposed to jump.
Since panning is continuous anyways, panning operations clearly can smooth 'scroll' without problems; it matches how people think of them to start with. Scrolling, especially scrolling large amounts, is not like that so (at least to me) using smooth scrolling feels wrong.
This still leaves you to figure out which operations users think of as panning ones and which ones they consider scrolling ones. Sometimes this is clear (my rule of thumb is that any continuous action is panning), but sometimes it is not; for example, should the mouse scrollwheel be considered panning or scrolling? In theory the scroll wheel is generally equivalent to cursor up and cursor down, which are discrete things (generally moving one line); however, I think most people use it in a more continuous manner and will expect it to smooth scroll.
(This is certainly how I find myself using a scrollwheel mouse; the scroll wheel is less for moving to a specific place in a document than for panning slowly through it.)
If you have well implemented smooth scroll you may want to use it even for small scrolling movements, such as cursor up/down. Beyond that, please don't, or at least have an option to not do it.