If you look up “computational economics” on wikipedia, you’ll find out all about software models that economists use to study game theory, recessions, scarcity, and so forth.
Tweak your search terms a bit, and google takes you to discussions about the economics of the computer industry–how Moore’s Law plays out in changing prices for compute power, why cloud computing and cheap GPUs are changing how much we expect to pay, how the mobile revolution is killing traditional PCs, what the job market looks like for us software geeks.
That’s all well and good.
But there is a third half of the computer+economics interaction that I don’t hear anybody talking about.
My buddy Ken Ebert likes to joke about incomplete thinking by saying, “There are 2 aspects of the issue…” — while he raises three fingers. :-) Interestingly, this three-fingered gesture is a symbol of sustainable development, which connects nicely to our theme of economics. Photo credit: \!/_PeacePlusOne (Flickr)
Project management 101 teaches that, when managing outcomes, you cannot alter scope, schedule, or cost (resources) without affecting at least one of the other dimensions. This interrelationship is known colloquially as the “Iron Triangle.” Sometimes we put “quality” in the middle to show how it is unavoidably shaped by choices on the other constraints:
Image credit: John M. Kennedy T (Wikimedia Commons)
Lots of Dilbert cartoons derive their humor from the unwillingness of the Pointy Haired Boss (PHB) to acknowledge this relationship. These cartoons are funny because they are so eerily similar to conversations we’ve all had, where someone wants us to deliver ultra-high quality, on a limited budget, in an aggressive timeframe, with a boatload of features.
It ain’t gonna happen, folks. We engineers are clever, but we’re not magicians. Triangles don’t work that way.
You’ve learned some good principles when you can articulate this geometry lesson.
But there’s more.
Truth 1: Scope is a trickster
Many well meaning managers and executives understand this trilemma, and they distance themselves from Dilbert’s PHB by acknowledging that something has to give. “I pick scope,” they’ll say. “We absolutely must have the product before the summer doldrums, and we only have X dollars to spend, but I’m willing to sacrifice a few features.”
This can give product management heartburn–feature sets sometimes hang together in ways that make slicing and dicing dangerous. An airplane that’s good at takeoffs but that can’t land is unlikely to be a commercial success. Good product managers will point this out, and they’ll be right.
In my experience, most programmer attitudes on speed fall into one of these categories:
Programmers with this mindset think about performance on occasion, but it’s not a big focus. Occasionally they’re forced to tackle problems because a particular design is too slow, a customer is unhappy, or new scaling requirements materialize. In such cases, they experiment until behavior improves, and then go back to the work they really care about.
Programmers with this mindset have a hard time not thinking about performance. Every design they do reflects elaborate consideration of how to minimize footprint and/or how to complete a task in the shortest possible time. (Note that those two priorities often conflict.) Programmers who are passionate about performance often feel like their laissez-faire counterparts are derelict in their duty.
I don’t think either of these extremes is healthy in all cases. I have seen programmers who chronically think about performance too late, creating large refactoring burdens and sabotaging their company’s success. Sometimes when you go from “make it work” to “make it fast” you find that all your original work is a waste, because a totally different design (even different tests, conceivably) is the only way forward; I wrote about this in “A Quibble with Martin’s ‘Optimize Later’ Notion“.
On the other hand, it is possible to be too passionate about performance; optimizing the performance of the dev team (by decreasing coding and testing time) is often a better business choice than optimizing execution speed in ways that make code more complex and harder to verify. I have encountered performance zealots disqualifying a perfectly good design on the grounds that it’s not performant enough in a use case that only 2 customers on the entire planet would ever care about. Not smart. As I’ve said many times, good code is balanced.
ThrustSSC — the first car to break the sound barrier. Sometimes speed is the ultimate criterion. However, most money is made on cars with more modest performance requirements. Photo credit: cmglee (Wikimedia Commons)
Let’s assume you buy my criticism of the extremes, and you’re willing to apply the “it depends” doctrine. Continue reading
In my first post about what constitutes “good code,” I claimed we were dealing with a complex question. This is why I distrust short answers.
So many competing concerns must be balanced to achieve goodness:
- Short-term revenue pressures
- Long-term strategic value
- Performance (many aspects)
- Scalability (up, down, across)
- Ease of use
- Conceptual integrity
- Alignment with the skills, temperament, interests, and tools of the team that owns it
- Cost vs. benefit (for some problems, quick and dirty is definitely “right”)
- Simplicity (separation of concerns)
More items undoubtedly belong on the list. Quite a balancing act!
Someone’s got this “balance” thing down! Photo credit: joãokẽdal (Flickr).
Pick a module, application, or subsystem that you know well, and grade its code according to how much its coders emphasize a few different dimensions (e.g., performance, testability, scalability, ease of use). Do you like the balance? Are any attributes being neglected?