Skip to main content

The Art of Writing Perfectly Dumb Code

Posted by editor on April 23, 2009 at 6:00 AM PDT

In a team-based software development environment, it has always been necessary to find the right balance between efficiency and clarity, between the clever and the readable. This is because software development entails two very important and very different types of productivity: that of the software itself (how much work gets done per millisecond or per CPU unit?), and that of the developers (how many hours are required for long-term maintain and enhancement of the software?).

Code that makes small processing efficiency gains at the cost of being difficult to maintain or enhance by future developers (or even by the original developer five years later) is more of a problem than a solution. The very clever eight lines that occupy an hour of a future developer's time for decoding its logic, are typically of less utility than 20 more straightforward lines. Perl is notorious (at least to me) for providing the capability for developer cleverness to go overboard in this way, enabling a piece of code to look more like an abstract puzzle than an encoding of a logical process into a symbolic language.

As it turns out, overly concise code that is difficult to understand for future developers can also present problems for compilers, resulting in a loss of processing efficiency, rather than a gain. Fewer lines or characters of source don't necessarily translate into fewer machine code steps.

This fact is clearly explained in the recent article The Developer Insight Series, Part 1: Write Dumb Code -- Advice from Four Leading Java Developers, written by Janice J. Heiss. In the article, Janice interviews Sun Technology Evangelist Brian Goetz and Java Champions Heinz Kabutz, Cay Horstmann, and Kirk Pepperdine.

Code readability is a key topic of discussion by the four experts--readability not only by humans, but also by compilers. Brian Goetz says:

Often, the way to write fast code in Java applications is to write dumb code -- code that is straightforward, clean, and follows the most obvious object-oriented principles. This has to do with the nature of dynamic compilers, which are big pattern-matching engines. Because compilers are written by humans who have schedules and time budgets, the compiler developers focus their efforts on the most common code patterns, because that's where they get the most leverage. So if you write code using straightforward object-oriented principles, you'll get better compiler optimization than if you write gnarly, hacked-up, bit-banging code that looks really clever but that the compiler can't optimize effectively.

Heinz Kabutz illustrates the tradeoffs between processing efficiency and code legibility by taking a single logical task (basic concatenation) and showing several different ways it can be coded. He then provides the benchmarking data for each example and discusses the advantages and disadvantages of that particular method. He warns against overly-clever coding:

In the early days of Java programming, I sometimes resorted to "clever" coding. For example, when I was optimizing a system written by a company in Germany, I changed the String addition to use StringBuffer after we had optimized the architecture and design of the system and wanted to improve things a bit. Don't read too much into microbenchmarks. Performance advantages come from good design and an appropriate architecture.

Cay Horstmann writes:

I learned over the years that it never pays to optimize code until after you profile. We all fret over caching values rather than recomputing them, eliminating layers, and so on. More often than not, it makes little difference in performance but introduces a huge headache in debugging.

Kirk Pepperdine sees writing dumb code and well-structured code as the two keys to performance and long-term maintainability:

While we write code to run on a machine, the primary consumers of code are humans. Dumb code tends to be more readable and hence more understandable. If we can iron out the twists, then we have a better chance of avoiding the dumb mistakes that clever code may hide from us...

... how does well-structured code help performance? Most performance problems can only be solved by adding or altering code in the application. I've found that if the code is well structured and loosely coupled, if the classes are cohesive, and the code uses delegation, I can avoid the whack-a-mole problem when I start to change code.

Even though I've been coding for nearly three decades, I found The Developer Insight Series, Part 1: Write Dumb Code -- Advice from Four Leading Java Developers interesting and enlightening. Writing overly-clever, unreadable code is surely a mistake junior developers are more apt to make than senior developers. But even senior developers and team leaders, caught up in the daily grind to meet the next release deadline, can easily forget that other consumer of their code--the compiler--and write code that is concise and clear to the experienced developer, which they believe is also sure to result in high processing efficiency; and yet the compiler, being a careful consumer and needing to account for all the possibilities with respect to how a processing thread may pass through that logic, won't reduce that source into maximally efficient byte-code.

Many thanks to Janice for coming up with the idea to do the interviews, and thanks to Brian and our Java Champions Heinz, Cay, and Kirk for providing their insight.


The latest Java Mobility Podcast is
Java Mobility Podcast 76: Sound of Motion, in which Vladimir Savchenko of Sound of Motion talks about their Java ME application that transforms their cycles into advanced cycling computer.


In Java Today, Janice J. Heiss gathers advice that may sound surprising to some Java developers, in her article The Developer Insight Series, Part 1: Write Dumb Code -- Advice From Four Leading Java Developers: "Over the years, developers have talked about their favorite code, funniest code, most beautiful code, how to write code, how not to write code, the obstacles to writing good code, what they love and hate about writing code, the process of writing code, and so on. In the process, they have provided a lot of insight that is worth preserving. In the first of a multipart series, we begin with some general advice: Write dumb code..."

The Flying Saucer team announces the release of Flying Saucer XML/CSS Rendering Library R8: "We are proud to present our R8 release. This release includes no changes since R8 release candidate 2. We once again thank the people who contributed to this release. Features: ImageMapReplacedElementFactory.java: Sample for handling image maps, submitted via users mailing list by elbart0 at free.fr on March 5, 2008. This sample is a work-in-progress..."

And Paulo Moreira reviews the EJB 3.1 Proposed Final Draft in his article EJB 3.1 - A Significant Step Towards Maturity: "EJB 3.1 introduces a new set of features which intends to leverage the potential of the technology. It is, in my opinion, a release of major importance, which brings capabilities which were most wanted since long ago, making it more able to fulfill the needs of modern enterprise applications, and contributing for an increased adoption..."


In today's Weblogs, Jitendra Kotamraju writes about JAX-WS RI 2.1.7/Metro 1.5 Released: "Metro team is pleased to release JAX-WS RI 2.1.7/Metro 1.5. JAX-WS RI team is pleased to announce the release of 2.1.7 version. It is also included in Metro 1.5. There was no 2.1.6(pretty much 2.1.5) java.net release as it was primarily created for JDK 6u14. As most of the effort has been going into JAX-WS RI 2.2, this is a minor release. Some of the changes since 2.1.5 are..."

John Ferguson Smart writes about An introduction to easyb at Devoxx: "The easyb talk I gave at Devoxx in November is now available on Parleys. Most people would agree that testing your code is a good thing. And there is little doubt that modern Test-Driven development practices, when applied well, can produce high quality software that is reliable, flexible and easy to maintain. However, one of the big problems that often happens when developers adopt Test-Driven Development is that they concentrate so much on the tests that they lose focus on what they are actually meant to be testing..."

And Jean-Francois Arcand writes about Grizzly 2.0.0-M1 released! With extra: History of Grizzly: "Today we are releasing our first Grizzly 2.0 release, which we are working on since almost 2 years. Get ready for the revolution! But how this Grizzly things started? It has been years since I've jumped into the blogosphere and started talking about Grizzly. Officially, Grizzly started in 2004 when Vivek Nagar and I talked about NIO..."


This week's java.net Poll asks "Which of the technologies highlighted at JavaOne 2009 is of greatest importance for the future of Java?" Today is the last full day of voting on this poll.


This week's Spotlight, titled Java + You = Innovation, reminds us that JavaOne is just around the corner: "It's that time of year again. The 2009 JavaOne conference takes place at the Moscone Center in San Francisco from June 2-5 and is being sponsored by Intel (a Platinum sponsor), JBoss, and Sony Ericsson. This year's technical and Birds-of-a-Feather (BOF) sessions are organized around four topics: Rich Media Applications and Interactive Content; Mobility; Services; and Core Technologies. You can view information on all the sessions now and get a $200 discount on early bird registration until April 22."


In the Forums, glassola asks for help with a Prblm creating two separate/independent JMS queues?: "Dear forum readers, I have a problem configuring separate JMS queues in GlassFish. What I would like to accomplish is to set up two different queues, Queue1 and Queue2. In the GlassFish administration console I added two separate destination queues with separate Physical Destinations (I assume that different PD:s are a must to separate them?) and one Connection Factory. I've also created two very simple Message Driven Beans (MDB) in NetBeans 6.5.1 and a Session Bean to post messages to these two JMS queues. Each MDB just consumes the text message and prints the text on System.out i.e. in the GlassFish log. The problem is that even if I send to those two queues the message ends up in the first MDB which should be mapped only to the first queue..."

stratum Cannot add node agents to cluster: "HI all, Sorry if I am asking a lame question but I am trying it for almost a week all ready and cannot solve the issue. I have 2 Solaris boxes with 3 zones - two onto one machine and third onto second. I want to have the GF DAS working into one zone and two nodes onto other two zones. I am creating the node agent for DAS, creating instance for DAS but when I do the node agent for the nodes - I cannot start the node agent - getting this error: [#|2009-04-22T10:37:30.350+0100|SEVERE| ..."

And peterdelaney is having difficulty applying JNDI and Serializable objects: "Hello; I am implementing the LifecycleListener interface in an implementation class called RuleServerLifecycleImpl. The RuleServerLifecycleImpl will create an object called RuleServer that will perform some remote messaging to a RV listener. The RV listener then publishes back to the RuleServer object. Once the application is up and running and the Client call into my application an EJB will be called which will then get a reference to the RuleServer bean via the JNDI tree and the EJB will call methods on the RuleServer object..."


Current and upcoming Java
Events
:

Registered users can submit event listings for the href="http://www.java.net/events">java.net Events Page using our href="http://today.java.net/cs/user/create/e">events submission form.
All submissions go through an editorial review before being posted to the
site.


Archives and Subscriptions: This blog is delivered weekdays as
the Java
Today RSS feed
. Also, once this page is no longer featured as the
front page of java.net it will be
archived along with other past issues in the href="http://today.java.net/today/archive/">java.net Archive.

In a team-based software development environment, it has always been necessary to find the right balance between efficiency and clarity, between the clever and the readable...

Comments

I am a junior developer but have had experience with "elegance" vs. "simplicity" when writing regular expressions for Snort rules. In the Sourcefire Snort class it is noted and demonstrated that when trying to write the regex to match a social security number formats it is faster to just use the dumb or'd together variants rather than doing recursive matching with parenthesis and $1 variables.