How To Go Slow. Do You Write Efficient Code? (artima.com)

14 points by manny21 ↗ HN
Summary: Computers make life easier because they're so fast, right? Well, yes and no. Do you write efficient code? The author reveals some disconcerting inefficiencies lurking in commonly used software and development practices.

5 comments

[ 2.7 ms ] story [ 20.7 ms ] thread
The number of layers of software between you and the device you're manipulating can be a problem, but only it costs more in terms of efficiency than in terms of programmer time. A lot of people seem to forget how valuable programmer time is, and abstractions which save it are therefore valuable.

How valuable? Since an abstraction can be used by any number of developers, its value is at least multiplicative. And since the developers have saved time, they can use that savings to accomplish even more. If the time is spent writing more abstractions, they may become exponentially more valuable.

Or not. There are two things suggested by this:

  1) If you spend all of your time writing abstractions, you won't write any applications.

  2) An abstraction's value is directly proportional to the number of programmers that use it.
Conversely:

  2') An abstraction becomes useless as it becomes harder to use.
"Harder to use", not "harder to understand". We use things we don't understand all the time - that's the point of abstraction.

But an abstraction that's hard to use is a different dragon. Consider OpenGL. It's an elegant layer of software to deal with the complexities of creating graphics applications that run in real time. They kept a lot in mind while writing it, and because of that, it's very powerful. But only developers who fully understand OpenGL can use it effectively. Since Direct3D is much easier to understand, but perhaps less powerful, it's a perfect example of the Musket Effect. Direct3D is a musket and OpenGL is a katana.

For any two untrained people, if you give one a musket and one a katana, it's likely that the one with a musket will win, if he scores a good hit. Both are abstractions of force, but the musket is decisively easier to use.

What if a 150 katanas and a 150 muskets are divided between 300 Spartans and they're pitted against each other in an epic warrior-ninja-vs-warrior-marksman battle? Well.. The Musket-Spartans will be remembered fondly, and the Katana-Spartans will enjoy their victory. A musket simply takes too long to reload.

But is a katana "better", then? No. Since each musket is easy to use and individually powerful, more people will begin using muskets. They'll bring one along while hunting, for example. Then the musket will be improved, and improved, and improved again. The result is an M-9 Beretta 9mm pistol. Now pit 150 of those against 150 katanas, and you can imagine how things will turn out.

And that's the Musket Effect: A linear increase in usability causes an exponential increase in power, given time.

I was reading this today at my job: http://msdn.microsoft.com/archive/default.asp?url=/archive/e... ... it's documentation that lets you use Direct3D 9 most effectively. Notice the easy-to-understand list. Each item uses simple words to succinctly deliver its message.

Contrast that with any documentation here: http://www.opengl.org/registry/ .... Those are manuals for each OpenGL extension. An 'extension' is simply a feature of a video card that a programmer can use. Except because the documentation is so technical, few programmers do, compared to the number using Direct3D.

Some say Direct3D is winning hearts and minds because it's backed by a huge corporation. That certainly helps. But it seems like Direct3D is more powerful because there are more quality engineers working on Direct3D than an OpenGL.

What's a lone wolf to do, then? Well, it takes time, but anyone who has each of those OpenGL manuals committed to memory will be far more powerful and way more productive than any given Direct3D programmer. Just look at John Carmack. So there are tradeoffs.

The best thing that any engineer could do fo...

I'm trying to install some popular diagnostic tools, downloaded from a popular computer manufacturer, onto my laptop, using a popular install program. The install has been using 100% of a CPU for half an hour.

So Greg is obviously in the dark but rather than post any actual details that could help identify and resolve the actual problem, he's decided instead to pontificate about stuff which may have nothing to do with what's really going on.

This could just be a case where the installer's algorithm is fine but an underlying library call isn't working properly (for example, poll on OSX is known to have problems. http://marc.info/?l=log&m=111515776629581&w=2 ). But without some actual information, we'll never know.

There seems to be no shortage of developers with poor problem solving skills.

Even if that is the case, his point still stands because someone (the OSX developers) didn't care enough about performance.
No, it means something may have changed in between the time the developers wrote the code and when he tried to run it. Or perhaps there's something interesting in his environment (e.g. a different file system than the installer supports). But since Greg didn't bother burdening anyone with details, we'll never know.

The link I posted is a perfect example of this - it's for the supervise utility from djb's daemontools. djb is one of sharpest programmers out there but I doubt he considered that years after he wrote daemontools someone might want to run it on a platform where poll behaves as it does.

  Every cycle's sacred
  Every cycle's great
  If a cycle is wasted
  God gets quite irate
With most people I've talked to, this approach turns into a religion pretty fast. In my opinion, you should use a naïve approach (within limits, recursive Fibonnaci definitions are exempt) until it becomes necessary to do things more efficiently. Of course this entails always keeping in mind who your users are and whether a certain design choice needs to remain in your code for a long time, something it seems this installer team didn't quite grasp.

But always choosing the most efficient algorithm leads to a program where code that runs for two milliseconds every minute runs 10 times faster for 3 times your development effort, with 3 bugs introduced in the process because you weren't paying attention.

  How much time is wasted? On my machine summing a billion bytes row-wise takes 9 seconds, whereas 
  summing them column-wise takes 51 seconds. The less sequential your data acccess, the slower
  your program will run.
Yes, if you sum gigabyte-sized arrays all the time, this is definitely something you should worry about. But not all problems require this kind of attention to low-level details. Most of the time you are searching an 8-byte array, in which case the choice of binary search vs. linear search is irrelevant.

Of course it pays to be aware of these things (you won't have to go hunting in the library when you hit a wall) but keeping them in mind at all times is more trouble than it's worth. There are more important things to worry about, for instance whether your unit tests cover every likely case.