This is a kind of geeky episode, but I think there is a lesson here that goes far beyond computer science. You might want to give it a go, even if programming is not your thing.
I am slowly updating a body of code made by other people. They optimized for the oddest things. For instance, when you get the profile of a person, you also get the profiles of the people who work for that person, including their pictures.
Sometimes, you see, in some application I’ve never worked on, that information is useful. But rather than make a way for our apps to ask, “hey, who is this guy the boss of?” and subsequently, “what do they look like?”, the system returns all that information whether you want it or not. Which makes all requests for a profile dramatically slower whether they need that information or not, and chews up bandwidth sending pictures that will never be used, and generally makes the world worse.
The people that wrote that code were carefully optimizing to reduce the number of round trips to the server. One app saves a couple of milliseconds while all other apps pay the price. While I disagree with that optimization in our case, I understand it. It comes, ultimately, from programmers who remember a different Internet. I guess. When requests took up that much extra time, wasted bandwidth was an even bigger problem.
Now there’s a new sheriff in town, and I’m applying my own optimizations. And while you might guess that I’m making services that very quickly return only the data you asked for, there is another optimization I find far more important. I am optimizing for clarity.
Right now I am maintaining a service with methods ‘getProfile’, ‘getFullProfile’, and (God help me) ‘getFullProfile2’. The well-intentioned architects of this system created a standard of providing structured comments for each method; but the doc block for two of the three methods mentioned above were copied from somewhere else and were just wrong.
Other methods in the system return partial data from a person’s profile, but often the names given to the data fields don’t match anything else. ‘prefName’ in one so-called profile might be ‘ub_emp_preferred_name’ in another. It’s madness.
Optimizing for clarity begins with recognizing that a person’s profile is a thing that can be clearly defined. “This is what a profile is,” one could declare. When you ask for a profile, there is no mystery what you are going to get. If you need more, you know how to ask.
There are times when such a rigid structure will cost you an extra server request or two, and it might make your server work a little extra. But here’s the secret: Engineer-days are worth more than processor-milliseconds. That’s true even if the processor-milliseconds add up to more than a day. A core running in a data center costs maybe a buck a day (though I suspect it’s much less). I’m embarrassed to tell you what I make for a day’s work, but it’s a bit more than a buck.
Design for clarity. I think this principle extends far past the software world. It certainly applies in industrial design, where even the simple objects we use every day benefit from a design that does not cause question marks to float over our heads. Simplicity is achieved; it does not happen on its own.
I am working on code that accepted complexity rather than working for simplicity, and in the end made more work for everyone. Perhaps, even if you are not a programmer, there is a lesson here: Work for simplicity. Work for clarity. Work less later, because your task is simple and clear.
“In simplicity there is strength. Postpone the subtle technique until after the program works and you will probably find it has become unnecessary.”
“Sturdy code is usually simple code.”
—John M. Nevison, The Little Book of BASIC Style
Been collecting quotes like this for a project I’m working on.
Your project sounds interesting.
I must confess that for the internals of a system, I’m probably a little too fanatical with the DRY (Don’t Repeat Yourself) ethic and that sometimes leads me to overly-elegant code. But it’s all in service of the interface — a simple set of methods that follow a clear pattern and return well-defined results.