Readability beats Performance (or, foldr is *not* evil)
James Hague (Programming in the 21st Century) points out that we really, really shouldn't be focusing on Optimization. To quote
Years ago, one of our developers optimized the heck out of one of the subsystems - to simplify things to the point of inanity, it was (not really, but whatever) akin to picking M items out of N buckets. There was loop unrolling, there were look-aheads, there may even have been matrix inversions. And it was completely, utterly, and absolutely un-understandable. Oh, it was massively efficient, in a process that was I-O bound anyhow, so nobody gave a crap. Over the next few years, at least three other people puzzled over that piece of code - the evil genius was long gone - and I had to untangle the puzzle each time (This is what is being solved for, blah, blah). In a fit of fury one evening, I rewrote the whole chunk in "plain code", with the obvious result - it is now readable, overall performance isn't affected one bit, and I've never been asked about that section again.
Which brings me, in a roundabout way, to erlang. I love it, it has made my life dramatically easier, its the greatest thing since sliced bread, etc., etc. But really folks, please stop writing your code like you're competing in the 17th annual obfuscated code contest!. If you really feel like it, go look at Fred's entry here, and quietly give up the chase (it wins. hands down. 'nuff said.). Well written erlang is a thing of beauty, and is remarkably easy to read! You don't have to ensure tail-recursion in everything you do! foldr is not evil!
I know, flogging a dead horse, etc. But seriously folks, don't worry about performance/optimization. Focus on readability, focus on maintainability, focus on repeatability, and when (and only when) necessary, focus on performance/optimization.
Life will be Good
Note: Repeatability - the ability to take the same solution, and repeat it in other areas. This is not the same as cut/paste, it actually refers to being able to look at the code, figure out how the solution works, and use that form of solution in other places. An oft overlooked trait in good code...
In any modern discussion of algorithms, there's mention of being cache-friendly, of organizing data in a way that's a good match for the memory architectures of CPUs. There's an inevitable attempt at making the concepts concrete with a benchmark manipulating huge--1000x1000--matrices. When rows are organized sequentially in memory, no worries, but switch to column-major order, and there's a very real slowdown. This is used to drive home the impressive gains to be had if you keep cache-friendliness in mind.
[...] Linked lists are a worst case, potentially jumping to a new cache line for each element. That's damning evidence against languages like Haskell, Clojure, and Erlang. Yet some naive developers insist on using Haskell, Clojure, and Erlang, and they cavalierly disregard the warnings of the hardware engineers and use lists as their primary data structure....Which really drives home a point that I've been making for years - with very very rare exceptions, the benefits of readability / maintainability / repeatability far far outweigh performance gains. Oh, I know, there are edge cases involving graphics, rendering on the screen, blah, blah, but frankly thats not where most people spend most of their time, for good or for evil.
...and they manage to write code where performance is not an issue.
Years ago, one of our developers optimized the heck out of one of the subsystems - to simplify things to the point of inanity, it was (not really, but whatever) akin to picking M items out of N buckets. There was loop unrolling, there were look-aheads, there may even have been matrix inversions. And it was completely, utterly, and absolutely un-understandable. Oh, it was massively efficient, in a process that was I-O bound anyhow, so nobody gave a crap. Over the next few years, at least three other people puzzled over that piece of code - the evil genius was long gone - and I had to untangle the puzzle each time (This is what is being solved for, blah, blah). In a fit of fury one evening, I rewrote the whole chunk in "plain code", with the obvious result - it is now readable, overall performance isn't affected one bit, and I've never been asked about that section again.
Which brings me, in a roundabout way, to erlang. I love it, it has made my life dramatically easier, its the greatest thing since sliced bread, etc., etc. But really folks, please stop writing your code like you're competing in the 17th annual obfuscated code contest!. If you really feel like it, go look at Fred's entry here, and quietly give up the chase (it wins. hands down. 'nuff said.). Well written erlang is a thing of beauty, and is remarkably easy to read! You don't have to ensure tail-recursion in everything you do! foldr is not evil!
I know, flogging a dead horse, etc. But seriously folks, don't worry about performance/optimization. Focus on readability, focus on maintainability, focus on repeatability, and when (and only when) necessary, focus on performance/optimization.
Life will be Good
Note: Repeatability - the ability to take the same solution, and repeat it in other areas. This is not the same as cut/paste, it actually refers to being able to look at the code, figure out how the solution works, and use that form of solution in other places. An oft overlooked trait in good code...
Comments