Optimizing for code readability vs efficiency

1,436 views
Skip to first unread message

Todd Sedano

unread,
Mar 28, 2013, 4:51:04 PM3/28/13
to software_cr...@googlegroups.com

Am I telling my students the right thing?

In my "craft of software development" course, I've noticed two competing philosophies. Several of my students believe that efficiency is the most important aspect of code, where as, I believe that code readability is the most important aspect of code. 

As a metaphor, I've been saying that their code should tell a story to the reader. Their job is to rework the code to tell a narrative. Just like story telling has conventions to signal to the reader what his happening and where the story is going, we too can use techniques to inform the reader about what is going on. 

Here's an example.  While solving the coin changer kata, one of my students was accessing denominations.at(i) and denomination.at(i+1) several times in the code. It was difficult to understand what was going on because the reader would loose track of how i, and i+1 were different. I suggested storing these two items into local variables to expose the intention of the code. 
smaller_coin = denomination.at(i)
larger_coin = denomination.at(i+1)
Then in the remainder of the code, it was easier to understand the logic since we were talking about using the smaller denomination coin or the larger denomination coin.

For compiled languages, compilers may further optimize readable code, and remove small inefficiencies. While this is "two extra lines of code" example, the compiler may do away with them. Ironically, most of my programming is in interpreted languages.

When I write code, I first try and solve the problem, then if there are inefficiencies, I improve them. When writing code, I do see value in considering the algorithmic complexity or Big O running time, e.g. a x N, vs b x N x log N vs c x N^2 (where a,b,c are some constants for operations.) I'd argue that we can write readable code that performs well within the alogirthimic complexity. Yet, I see many of my students more worried about small performance optimizations, they are trying to shrink the constants in the equation at the expense of code readability.

Just yesterday I was doing a code-read-through with one of my students. When we were done, I reworked one of her methods to show how code readability could be improved. She was very concerned about sacrificing efficiency at the expense of writing readable code. When I was done tweaking her method, ironically, the code was more efficient than her original code. 

I do realize that extremely optimized code is impossible to read. At a Splash 2011 keynote, Markus Püschel described how they do automatic performance programming. Their goal is to optimize C libraries to the specific CPU chipset, level 1, level 2 caches. Their search space includes how much loop unrolling to do, how big to segment arrays, and any other compiler trick they can think of. Their software will explore this search space for each chipset. A small change in the L2 cache might have impacts on their tuned code. Here was my take-a-way: the highly optimized machine generated code (number in millions of lines of code) is completely unreadable. I assume that the code they use to run their machine learning and heuristics is readable to their programers, while what they produce is only readable to the machine, and that doesn't matter, because no user of it will ever read it. 

I do agree that the inner loop of a highly used function should be highly optimized, however, I'd hope we could make that code readable too. 

I'm probably preaching to the choir, but if you have any advice on how to convey the message differently, I'd love to hear it. If you disagree with me, help me understand your perspective.

Regards,

Todd

P.s. I can't wait to present some of my research data at the next SCNA. 

Todd Sedano
Director of Software Engineering
Carnegie Mellon University
Silicon Valley Campus
Developing Software Leaders (TM)
T: 650-335-2812


Carlos Peix

unread,
Mar 28, 2013, 5:09:18 PM3/28/13
to software_cr...@googlegroups.com
Hi Todd,

I guess you need to introduce the ROI concept on the code "form".
  • How much value you win with speed optimization? it's needed? (justified by numbers)
  • How much value you win with clean code? it's needed? (justified by numbers)
I tend to err on the clean code side unless speed optimization is needed, justified by numbers, in *that* case.

Good luck in SCNA.

----------------------------------
Carlos Peix

--
You received this message because you are subscribed to the Google Groups "software_craftsmanship" group.
To unsubscribe from this group and stop receiving emails from it, send an email to software_craftsma...@googlegroups.com.
To post to this group, send email to software_cr...@googlegroups.com.
Visit this group at http://groups.google.com/group/software_craftsmanship?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Michael Feathers

unread,
Mar 28, 2013, 5:55:41 PM3/28/13
to software_cr...@googlegroups.com
There is an argument you can make with exercises that lays the whole thing to rest.  Show them how it is easy to optimize readable code, but hard to make heavily optimized code readable.  

If they can see the relative effort in those two tasks, it should be obvious to them that readability is the best default for nearly all code.

Adam Sroka

unread,
Mar 28, 2013, 6:29:53 PM3/28/13
to software_cr...@googlegroups.com
On Thu, Mar 28, 2013 at 1:51 PM, Todd Sedano <todd....@sv.cmu.edu> wrote:

Am I telling my students the right thing?

Yes. 
 
<snip>

Just yesterday I was doing a code-read-through with one of my students. When we were done, I reworked one of her methods to show how code readability could be improved. She was very concerned about sacrificing efficiency at the expense of writing readable code. When I was done tweaking her method, ironically, the code was more efficient than her original code. 


I have encountered an identical scenario, and many of the coaches/trainers I have worked with over the years have as well.

 
I do realize that extremely optimized code is impossible to read. At a Splash 2011 keynote, Markus Püschel described how they do automatic performance programming. Their goal is to optimize C libraries to the specific CPU chipset, level 1, level 2 caches. Their search space includes how much loop unrolling to do, how big to segment arrays, and any other compiler trick they can think of. Their software will explore this search space for each chipset. A small change in the L2 cache might have impacts on their tuned code. Here was my take-a-way: the highly optimized machine generated code (number in millions of lines of code) is completely unreadable. I assume that the code they use to run their machine learning and heuristics is readable to their programers, while what they produce is only readable to the machine, and that doesn't matter, because no user of it will ever read it. 


So, essentiallly, our compiler doesn't do what we want it to do so we turned our team into a compiler. Good luck with that. 

 
I do agree that the inner loop of a highly used function should be highly optimized, however, I'd hope we could make that code readable too. 


Which 9/10 times in my experience is as simple as moving the offending code to a well named location and calling it from higher-level, readable code. 
 
I'm probably preaching to the choir, but if you have any advice on how to convey the message differently, I'd love to hear it. If you disagree with me, help me understand your perspective.


The way that I explain it goes something like this: 

Write clean code and refactor it continuously. If it is too slow for the customer's needs profile it. When the profiler says that line X is taking a bunch of time go there and read what it says. You should be able to understand it and improve it because it is clean. 

Optimizing too early causes the same kind of problems that writing the unit tests last does. You will discover that there is a certain amount of restructuring you have to do just to get to the point where you can optimize (or test) the right thing. 

Nigel

unread,
Mar 29, 2013, 4:11:08 AM3/29/13
to software_cr...@googlegroups.com
"Make it work, make it right, make it fast", Lampson - http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast

"Premature optimization is the root of all evil", Knuth - http://c2.com/cgi/wiki?PrematureOptimization

Fox
-- 
@sleepyfox


On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:

Am I telling my students the right thing?

Yes. 

Philip Schwarz

unread,
Mar 29, 2013, 11:35:40 PM3/29/13
to software_cr...@googlegroups.com
I believe that code readability is the most important aspect of code. 
Explain to them why readability is so important. I like to do that by getting them to read Kent Beck's explanation in Chapter 4 of his book: Implementation Patterns [1]):

"Thirty years ago Yourdon and Constantine in Structured Design identified economics as the underlying driver of software design. Software should be designed to reduce its overall cost. The cost of software is divided into the initial cost and the cost of maintenance:

cost.total = cost.develop + cost.maintain

Once the industry gained experience with software development, it was a big surprise to many that the cost of maintenance is much higher than the cost of initial development. (Projects with little or no maintenance should use a very different set of implementation patterns from those presented in the remainder of this book.)

Maintenance is expensive because understanding existing code is time-consuming and error-prone. Making changes is generally easy when you know what needs changing. Learning what the current code does is the expensive part. Once the changes are made, they need to be tested and deployed.

cost.maintain = cost.understand + cost.change + cost.test + cost.deploy

One strategy for reducing overall cost is to invest more in initial development in hope of reducing or eliminating the need for maintenance. Such efforts have generally failed to reduce overall costs. When code needs to change in unanticipated ways, no amount of forethought can perfectly prepare the code for change. The premature attempts to make the code general enough to meet future needs often interfere with the unanticipated changes that turn out to be necessary.

Substantially increasing the up-front investment in software runs counter to two important economic principles: the time value of money and the uncertainty of the future. Since a dollar today is worth more than a dollar tomorrow, in principle an implementation strategy should generally encourage deferring costs. Also, because of uncertainty an implementation strategy should generally take immediate benefits in preference over possible long-term benefits. While this may sound like a license to hack without regard for the future, the implementation patterns are focused on ways to gain immediate benefit while setting up clean code for ease of future development.

My strategy for reducing overall costs is to ask all programmers to address the cost of understanding code during the maintenance phase by focusing on communicating, programmer-to-programmer. The immediate benefits of clear code are fewer defects, easier sharing of code, and smoother development."

In Four Patterns at the Heart of Good Programming Style [2] I have a few slides (16-25) on the above passage. Feel free to show them to your students if you wish (before you do that, please tell them the thoughts are Kent Beck's and show them the book's details/front cover).


On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:

Philip Schwarz

unread,
Mar 30, 2013, 12:07:10 AM3/30/13
to software_cr...@googlegroups.com
Hey Todd, you said: "While solving the coin changer kata, one of my students was accessing denominations.at(i) and denomination.at(i+1) several times in the code. It was difficult to understand what was going on because the reader would loose track of how i, and i+1 were different. I suggested storing these two items into local variables to expose the intention of the code. 
smaller_coin = denomination.at(i)
larger_coin = denomination.at(i+1)
Then in the remainder of the code, it was easier to understand the logic since we were talking about using the smaller denomination coin or the larger denomination coin."

When you do that, I would also consider doing the following:
Philip

On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:

Philip Schwarz

unread,
Mar 30, 2013, 12:57:48 AM3/30/13
to software_cr...@googlegroups.com
>She was very concerned about sacrificing efficiency at the expense of writing readable code
Again, Kent Beck has some useful thoughts in Implementation Patterns and Smalltalk Best Practice Patterns. See slides 52-74 of the presentation I mentioned in an earlier comment.

Here are some quotes:

"The trick to getting good performance is using methods as a lever to make your performance measurement and tuning more effective."

"In my experience, better factored code, with lots of small methods, both allows more accurate and concise performance measurement (because there aren't little snippets of code duplicated all over) and provides leverage for tuning (through techniques like Caching Instance Variable)." 

"The combination of faster CPUs and the strongly localized nature of performance bottlenecks makes code performance an issue best left until you can gather statistics from realistic data sets"

"Overall, the goal of breaking your program into methods is to:
  • communicate your intent clearly with your reader
  • provide for future flexibility
  • set yourself up for effective performance tuning where necessary"
Philip

On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:

Philip Schwarz

unread,
Mar 30, 2013, 1:16:51 AM3/30/13
to software_cr...@googlegroups.com
>Make it work, make it right, make it fast

Jeff Langr wrote about "make it run, make it right, make it fast" in "Essential Java Style: Patterns for Implementation":

"The COMPOSED METHOD pattern is the centrepiece of this book. If you absorb one thing from Essential Java Style, make it how to use COMPOSED METHOD to organize your classes. Good class organization is what effective maintenance is all about.
A simple mantra to remember for class development is "make it run, make it right, make it fast". COMPOSED METHOD and the remainder of the patterns in this book are the "make it right" part of the mantra."

By the way, Composed Method and 3 other highly related patterns are the subject of the presentation I mentioned in an earlier comment.

Here are just a few snippets from the book:

MAKING IT RUN

...
At this point, you will have a class that can be used by the client code - "make it run." Is that enough?
While your class may run just fine, you will not have a class that can be easily maintained or extended.
...
MAKING IT RIGHT

After you have completed the first three steps in the development cycle and you have a handful of lengthy methods, your job is to "make it right".
Making it right means applying the patterns in this book to your class to make it as easily readable and maintainable as possible. COMPOSED METHOD is the starting point.
...

MAKING IT FAST

...
Modifications to increase performance usually are made at the expense of easily understood code. You will need to add comments to explain why things were done that way. Your code will become less maintainable. The implication of these downsides is that you should always save performance modifications until the last step. Even them, only implement them as a last resort.

Philip

Tim Ottinger

unread,
Mar 30, 2013, 4:07:14 AM3/30/13
to software_cr...@googlegroups.com

The code you write is not the code that runs, and can constrain the shape of the code that runs.

Many people are doiing efficiency by old wives' tales. They remember things that used to be true for a given language on a given compiler with a given optimization setting on a certain operating system on a given chipset.

Think about the code generators, the optimizers, the jitter, the microcode, the parralel pipelines, etc. This really isn't 1978 anymore. The correlation between what you write and what it runs is rather loose.

What if a chip version change were to change the heuristics, so you have pessimized the program with your hand-crafted loop-unrolled, extra-primitiveized code? What if you've had a case of "optimizer feature envy" and made it impossible for the runtime to arrange locality of reference so it can make good use of L1 cache? Cache misses are a huge performance spoiler, but indirect function calls within cache are no big deal.

A lot of people are terrified of stack frames and variables that resolve to registers.

We fear too many of the wrong things.

The fact is that other than good algorithms and clean code, there is less and less we can reliably say about how our code will perform.

Of course, waiting on networks or databases will have more impact than microefficiencies.

That's just what I have come to understand. My friends who wrote games with high refresh rates tell me that they still had a lot of profiling and magic rework to get their games to be smooth and responsive.

Tim

--

Jon Jagger

unread,
Mar 30, 2013, 5:10:52 AM3/30/13
to software_cr...@googlegroups.com
On Mar 28, 2013 9:51 PM, "Todd Sedano" <todd....@sv.cmu.edu> wrote:

Am I telling my students the right thing?

In my "craft of software development" course, I've noticed two competing philosophies. Several of my students believe that efficiency is the most important aspect of code, where as, I believe that code readability is the most important aspect of code. 

SNIP
 
I'm probably preaching to the choir, but if you have any advice on how to convey the message differently, I'd love to hear it. If you disagree with me, help me understand your perspective.


Some thoughts...

1) When I was much younger than I am now I used to tilt the balance in favour of optimization/encapsulation over readability/testability. Now I am older I realize the balance is better adjusted towards readablity/testability. I think that experience is probably quite common. But I'm pretty sure if I could go back in time and tell myself that I would ignore my own advice. And at some level I would applaud my younger self for ignoring the advice since I like to find things out for myself. If that matches with your experience too then that is a _personal_ story you can tell as context.

2) At some level I think people only really understand something if they experience it themselves. So how about asking each student to do the same exercise twice. Once in the most efficient way in terms of speed, and once in the most efficient way in terms of readability. That gets marked and maybe you can even see if the supposedly faster one is actually faster across the whole group. But mostly your doing this to set up the second part of the exercise.
In the second part to the exercise, you give each student two other students programs as their starting point - one optimized for readability written by another student, and one optimized for speed written by another (different) student. Then ask them to make the same modification on both programs. That way they get to experience 
a) rewriting code where the intent was readability
b) rewriting code where the intent was not readability
c) seeing after a) and b) which code actually comes out fastest/more readable
d) a proper 'experiment' designed to enhance learning


HTH
Cheers
Jon 



George Dinwiddie

unread,
Mar 30, 2013, 12:09:37 PM3/30/13
to software_cr...@googlegroups.com
Tim,

Excellent points! I wonder how many people here have looked at the
assembler output from their compiler. I haven't done it since the
mid-1990s, but I was amazed at the code that was generated (from C).
There's no way I could write code that efficient, and certainly couldn't
have maintained it.

- George
> <mailto:todd....@sv.cmu.edu>> wrote:
>
>
> Am I telling my students the right thing?
>
> In my "craft of software development" course, I've noticed two
> competing philosophies. Several of my students believe that
> efficiency is the most important aspect of code, where as, I believe
> that code readability is the most important aspect of code.
>
> As a metaphor, I've been saying that their code should tell a story
> to the reader. Their job is to rework the code to tell a narrative.
> Just like story telling has conventions to signal to the reader what
> his happening and where the story is going, we too can use
> techniques to inform the reader about what is going on.
>
> Here's an example. While solving the coin changer kata, one of my
> students was accessing denominations.at <http://denominations.at>(i)
> and denomination.at <http://denomination.at>(i+1) several times in
> the code. It was difficult to understand what was going on because
> the reader would loose track of how i, and i+1 were different. I
> suggested storing these two items into local variables to expose the
> intention of the code.
> smaller_coin = denomination.at <http://denomination.at>(i)
> larger_coin = denomination.at <http://denomination.at>(i+1)
> T: 650-335-2812 <tel:650-335-2812>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "software_craftsmanship" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to software_craftsma...@googlegroups.com
> <mailto:software_craftsmanship%2Bunsu...@googlegroups.com>.
> To post to this group, send email to
> software_cr...@googlegroups.com
> <mailto:software_cr...@googlegroups.com>.
> Visit this group at
> http://groups.google.com/group/software_craftsmanship?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "software_craftsmanship" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to software_craftsma...@googlegroups.com.
> To post to this group, send email to
> software_cr...@googlegroups.com.
> Visit this group at
> http://groups.google.com/group/software_craftsmanship?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
----------------------------------------------------------------------
* George Dinwiddie * http://blog.gdinwiddie.com
Software Development http://www.idiacomputing.com
Consultant and Coach http://www.agilemaryland.org
----------------------------------------------------------------------

Philip Schwarz

unread,
Mar 31, 2013, 8:21:36 AM3/31/13
to software_cr...@googlegroups.com
Just an idea....in the spirit of Martin Fowler's "global data is always guilty until proven innocent" and the Agile manifesto's "We have come to value X over Y", how about:

We have come to consider optimisation premature until proven necessary. That is, until a program is found too be insufficiently fast, we favour speed of program comprehension over speed of program execution.

Philip

On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:

George Dinwiddie

unread,
Mar 31, 2013, 2:52:59 PM3/31/13
to software_cr...@googlegroups.com
Philip,

On 3/31/13 8:21 AM, Philip Schwarz wrote:
> Just an idea....in the spirit of Martin Fowler's "global data is always
> guilty until proven innocent" and the Agile manifesto's "We have come to
> value X over Y", how about:
>
> We have come to consider optimisation premature until proven necessary.
> That is, until a program is found too be insufficiently fast, we favour
> speed of program comprehension over speed of program execution.

Nice!

- George

>
> Philip
>
> On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:
>
>
> Am I telling my students the right thing?
>
> In my "craft of software development" course, I've noticed two
> competing philosophies. Several of my students believe that
> efficiency is the most important aspect of code, where as, I believe
> that code readability is the most important aspect of code.
>
> As a metaphor, I've been saying that their code should tell a story
> to the reader. Their job is to rework the code to tell a narrative.
> Just like story telling has conventions to signal to the reader what
> his happening and where the story is going, we too can use
> techniques to inform the reader about what is going on.
>
> Here's an example. While solving the coin changer kata, one of my
> students was accessing denominations.at <http://denominations.at>(i)
> and denomination.at <http://denomination.at>(i+1) several times in
> the code. It was difficult to understand what was going on because
> the reader would loose track of how i, and i+1 were different. I
> suggested storing these two items into local variables to expose the
> intention of the code.

Philip Schwarz

unread,
Mar 31, 2013, 11:26:09 PM3/31/13
to software_cr...@googlegroups.com
Thank you.
> an email to software_craftsmanship+unsub...@googlegroups.com.

Philip Schwarz

unread,
Apr 1, 2013, 12:41:04 AM4/1/13
to software_cr...@googlegroups.com
Increasing the speed with which code can be comprehended saves a lot of money (by lowering the cost of maintenance).

Speed, Money, what's not to like?

Here is some help from the experts to leverage your students' obsession with speed and introduce them to the importance of speed of comprehension.

Jeff Langr in "Effective Java Style":

"If you cannot look at a method and rapidly determine what it is doing, then it is doing too much.

About Composed Method: "Rapid understanding is most important here—it should take me no more than a minute or two to understand what a developer intended the method to do."

Jeff Langr in "Agile Java - Crafting Code with Test Driven Development":

"Most of the methods you write should be between one and half a dozen lines. Some methods might be between half a dozen and a dozen or so lines. If your methods are regularly this length or even longer, you should work on refactoring them. The primary goal is to ensure that methods can be rapidly understood and maintained."

Joshua Kerievsky in "Refactoring to Patterns": 

About the "Compose Method" refactoring:

Problem: "You can't rapidly understand a method's logic."
Solution: "Transform the logic into a small number of intention-revealing steps at the same level of detail."

"A Composed Method is a small, simple method that you can understand in seconds."

"Before this refactoring, it would take a little time to understand what the method was doing. After this refactoring, I can rapidly understand what the method does in one second. This is a typical result of applying Compose Method."

Robert Martin in "Clean Code":

"Our goal, as authors, is to make our code as easy as possible to understand. We want our code to be a quick skim, not an intense study. We want to use the popular paperback model whereby the author is responsible for making himself clear and not the academic model where it is the scholar’s job to dig the meaning out of the paper."

Philip

On Thursday, 28 March 2013 20:51:04 UTC, Todd Sedano wrote:

Philip Schwarz

unread,
Apr 1, 2013, 12:45:23 AM4/1/13
to software_cr...@googlegroups.com
great thoughts.

>doing efficiency by old wives' tales
>you have pessimized the program
again, great.

Philip
To unsubscribe from this group and stop receiving emails from it, send an email to software_craftsmanship+unsub...@googlegroups.com.

Tim Ottinger

unread,
Apr 1, 2013, 8:22:05 AM4/1/13
to software_cr...@googlegroups.com
Your Robert Martin quote is a Tim Ottinger quote.

But I'm happy if you want to lend his authority to it.




--
You received this message because you are subscribed to the Google Groups "software_craftsmanship" group.
To unsubscribe from this group and stop receiving emails from it, send an email to software_craftsma...@googlegroups.com.

To post to this group, send email to software_cr...@googlegroups.com.
Visit this group at http://groups.google.com/group/software_craftsmanship?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

J. B. Rainsberger

unread,
Apr 2, 2013, 12:31:10 PM4/2/13
to software_cr...@googlegroups.com
On Thu, Mar 28, 2013 at 5:51 PM, Todd Sedano <todd....@sv.cmu.edu> wrote:

Am I telling my students the right thing?

If you're looking for a Single Right Thing, then no. :)
 
In my "craft of software development" course, I've noticed two competing philosophies. Several of my students believe that efficiency is the most important aspect of code, where as, I believe that code readability is the most important aspect of code.

"The most important" aspect of code doesn't and can't exist. You and I can spend 5 minutes and imagine a context where any (reasonble) given aspect of code appears "most important". I can think of situations in which correctness doesn't matter much, speed doesn't matter much, maintainability doesn't matter much.

Thus, my answer in an exercise: which aspect of code do *you* think is most important? Now, let's imagine a situation in which we'd generally consider a *different* aspect of code even more important than this "most important" one. Repeat until bored.

 As a metaphor, I've been saying that their code should tell a story to the reader. Their job is to rework the code to tell a narrative. Just like story telling has conventions to signal to the reader what his happening and where the story is going, we too can use techniques to inform the reader about what is going on. 

While I agree, I see a circular argument here, which tends only to convince people predisposed to believing it anyway.

One anecdote: pick some legacy code, start cleaning it up, and it usually speeds up. Why? The fastest code is no code, and cleaning legacy code usually results in removing code.

Another anecdote: slow legacy code usually does crazy things (read thedailywtf.com for 10 examples), and when we clean it up, we get rid over one or two really crazy things that used to go to some funky database, and now it runs in memory. Those improvements seem to affect execution speed a lot more than clever code optimisations do.

I'm probably preaching to the choir, but if you have any advice on how to convey the message differently, I'd love to hear it. If you disagree with me, help me understand your perspective.

I think I've done that here. I hope I have. What do you think?
-- 
J. B. (Joe) Rainsberger :: http://www.myagiletutor.com :: http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

Philip Schwarz

unread,
Apr 2, 2013, 5:22:05 PM4/2/13
to software_cr...@googlegroups.com
>Your Robert Martin quote is a Tim Ottinger quote.
thanks for the correction.
To unsubscribe from this group and stop receiving emails from it, send an email to software_craftsmanship+unsub...@googlegroups.com.

To post to this group, send email to software_cr...@googlegroups.com.
Visit this group at http://groups.google.com/group/software_craftsmanship?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Philip Schwarz

unread,
Apr 6, 2013, 8:54:30 AM4/6/13
to software_cr...@googlegroups.com
From Card 48 of Agile in a Flash [1], which is called "Refactoring Inhibitors":

Premature performance infatuation: Don't let baseless performance fear stifle cohesive designs. Make it run, make it right, and only then make it fast.

Philip



On Friday, 29 March 2013 08:11:08 UTC, Nigel wrote:

Philip Schwarz

unread,
Apr 6, 2013, 10:07:29 AM4/6/13
to software_cr...@googlegroups.com
>"The most important" aspect of code doesn't and can't exist. 

any recommendations/opinions regarding the viewpoint expressed (for example) in Michael Feathers "readability is the best default for nearly all code" ?

Just digging for wisdom.

Philip

Ron Jeffries

unread,
Apr 6, 2013, 12:56:25 PM4/6/13
to software_cr...@googlegroups.com
Philip,

On Apr 6, 2013, at 10:07 AM, Philip Schwarz <philip.joh...@googlemail.com> wrote:

>"The most important" aspect of code doesn't and can't exist. 

any recommendations/opinions regarding the viewpoint expressed (for example) in Michael Feathers "readability is the best default for nearly all code" ?

Just digging for wisdom.

I think it is at least the best default. I think almost all code can be quite readable and that neither speed nor storage are likely to be negatively impacted by clarity.

Ron Jeffries
I'm really pissed off by what people are passing off as "agile" these days.
You may have a red car, but that does not make it a Ferrari.
  -- Steve Hayes

J. B. Rainsberger

unread,
Apr 6, 2013, 1:25:43 PM4/6/13
to software_cr...@googlegroups.com
On Sat, Apr 6, 2013 at 11:07 AM, Philip Schwarz <philip.joh...@googlemail.com> wrote:
>"The most important" aspect of code doesn't and can't exist. 

any recommendations/opinions regarding the viewpoint expressed (for example) in Michael Feathers "readability is the best default for nearly all code" ?

I had a slightly rambling answer, which I decided to turn into a blog post. Please don't think I'm hit-whoring: http://link.jbrains.ca/YZWAgX

Short version: I agree, but you must know when to break the rules. (You've all seen the Golden Child, right?)
-- 
Message has been deleted

J. B. Rainsberger

unread,
Apr 6, 2013, 1:27:47 PM4/6/13
to software_cr...@googlegroups.com
On Sat, Apr 6, 2013 at 1:56 PM, Ron Jeffries <ronje...@acm.org> wrote:
Philip,

On Apr 6, 2013, at 10:07 AM, Philip Schwarz <philip.joh...@googlemail.com> wrote:

>"The most important" aspect of code doesn't and can't exist. 

any recommendations/opinions regarding the viewpoint expressed (for example) in Michael Feathers "readability is the best default for nearly all code" ?

Just digging for wisdom.

I think it is at least the best default. I think almost all code can be quite readable and that neither speed nor storage are likely to be negatively impacted by clarity.

I think of it this way: increasing clarity rarely forces me to sacrifice efficiency, but it often forces me to do something different from what I'd expected to do. Often it actually encourages me to increase efficiency through conciseness.
-- 

Dave Rooney

unread,
Apr 6, 2013, 2:26:57 PM4/6/13
to software_cr...@googlegroups.com
On 13-04-06 12:56 PM, Ron Jeffries wrote:
On Apr 6, 2013, at 10:07 AM, Philip Schwarz <philip.joh...@googlemail.com> wrote:

>"The most important" aspect of code doesn't and can't exist. 

any recommendations/opinions regarding the viewpoint expressed (for example) in Michael Feathers "readability is the best default for nearly all code" ?

Just digging for wisdom.

I think it is at least the best default. I think almost all code can be quite readable and that neither speed nor storage are likely to be negatively impacted by clarity.

Once upon a time in the last century, I worked with a guy who wrote the most beautiful code I've ever seen.  Most of our work at the time was in Clipper, but there were a number of times we had to drop down into C and even x86 assembler in order to add functionality and/or improve performance.

What really struck me while working with him (we paired long before it was called that), was that he was able to write beautiful, clear, expressive code in C... the best I had ever seen!  Even his assembly code was a pleasure to read.  To this day 20+ years later I strive to write code like his.

Making something fast doesn't mean that you need to make it unreadable.

Dave...

Nicholas Robinson

unread,
Apr 6, 2013, 3:39:00 PM4/6/13
to software_cr...@googlegroups.com
I really like your blog post, because it brings to the fore the very nature of what it is that often evades consciousness - Context.  I dont like the pithy statement "Premature performance infatuation" because it is not only loaded (infatuation and premature are both context based) but it is also too black and white.  I work in a space where if the FIRST thought is not Performance (with a capital P), then it wont matter that it runs or that its even right.  A misstep with performance can result in a complete re-write.  

These pithy statements lack context.  Once and only once is a great axiom or principle, but even it is context based.  Premature infatuation with the removal of duplication?  Who cares about duplication when we are just knocking up a test program to work through a thought process or design in mind? Duplication is a guideline, a principle to be "considered" even when building production code.  As an example, it is possible in C# to improve data structure performance in tight for-lops or hot code-paths by employing duplication as a tool, rather than factoring it out and hoping for jit level in-lining of the methods.  And it is still possible to make the code look beautiful.

As someone who plays a role in hiring for my company, since 2009 when I arrived here in Chicago, I have interviewed more than 30 candidates, and not one has had any deep appreciation of what it means to think about performance.  At least 75% of them were agilers.  To be sure, they have often been worth their salt from an agile perspective, but theres always been a perceived view that its more important that the code is well factored, and that with all of these good programming/craftsman practices embodied, the code should be fast enough.  It rarely ever is.

Nick.



--
You received this message because you are subscribed to the Google Groups "software_craftsmanship" group.
To unsubscribe from this group and stop receiving emails from it, send an email to software_craftsma...@googlegroups.com.

Ron Jeffries

unread,
Apr 6, 2013, 8:13:55 PM4/6/13
to software_cr...@googlegroups.com
Nicholas,

On Apr 6, 2013, at 3:39 PM, Nicholas Robinson <mr.nichola...@gmail.com> wrote:

I really like your blog post, because it brings to the fore the very nature of what it is that often evades consciousness - Context.  I dont like the pithy statement "Premature performance infatuation" because it is not only loaded (infatuation and premature are both context based) but it is also too black and white.  I work in a space where if the FIRST thought is not Performance (with a capital P), then it wont matter that it runs or that its even right.  A misstep with performance can result in a complete re-write.  

I have worked with computers with 256 bytes of memory and computers with many GB. I have worked with computers that executed ten instructions per second, and millions. In none of those cases have i ever needed to put performance first.

So I'd really like to hear more about your environment.

Ron Jeffries
I know we always like to say it'll be easier to do it now than it
will be to do it later. Not likely. I plan to be smarter later than
I am now, so I think it'll be just as easy later, maybe even easier.
Why pay now when we can pay later?

J. B. Rainsberger

unread,
Apr 6, 2013, 10:09:54 PM4/6/13
to software_cr...@googlegroups.com
On Sat, Apr 6, 2013 at 4:39 PM, Nicholas Robinson <mr.nichola...@gmail.com> wrote:
 
As someone who plays a role in hiring for my company, since 2009 when I arrived here in Chicago, I have interviewed more than 30 candidates, and not one has had any deep appreciation of what it means to think about performance.  At least 75% of them were agilers.  To be sure, they have often been worth their salt from an agile perspective, but theres always been a perceived view that its more important that the code is well factored, and that with all of these good programming/craftsman practices embodied, the code should be fast enough.  It rarely ever is.

Worth noting: I know very little about hand-tuned code, unless you count using StringBuffer in Java. When I work in poorly-performing legacy code, cleaning up the design has always resulted in a satisfactory improvement in execution speed or memory usage (very rarely both). What looks to some like an effort to reduce the number of instances the program creates, I see as simply removing duplication or pushing concreteness up the call stack. Quite often, the two have similar results. Also worth noting: I tend not to work in environments where deepening the call stack has dire consequences; I tend to work in environments where people occasionally do things that deserve mention at thedailywtf.com, like store their database schema in the database, or join 12 tables when 3 would do the job. This kind of thing.

My point remains, though: when we turn novice-level rules of thumb into "forever rules", we lose the context, and we give up a part of ourselves.
-- 

Nicholas Robinson

unread,
Apr 6, 2013, 11:37:48 PM4/6/13
to software_cr...@googlegroups.com
Ron,

I work in high frequency trading and options market making. I am sure we could all learn something from you too.  Before I entered this space, with over thirty years of real programming (having written my first programs at eight years old) I had the same experiences or views as your self. Its a demanding environment, thats all I can say. Do we strive for craftsman style code every single day? Yes. Do we have to focus more on performance over all else on an almost daily basis- yes. This isnt an opinion or a subjective experience; its simply a fact I myself have had to come to terms with given my own background in agile development.

Nick.

Sent from my iPad 2

Sleepyfox

unread,
Apr 7, 2013, 6:49:11 AM4/7/13
to software_cr...@googlegroups.com

A good friend of mine works in HFT, but in my 25 years of commercial software development experience I've only come across one other case where performance was the primary criteria. I would suggest that in more than 99% of cases, performance is not the problem, and where it *appears* to be the problem it is usually just a symptom of a different problem - in my experience usually poor design.

This seems to echo the experience of people considerably more experienced and accomplished than I am, so I'm pretty confident in applying it as a rule of thumb, meaning that while I recognise that in rare cases performance is an issue (context is crucial), in the vast majority of cases Beck's Law applies: "A programmer generates complexity in inverse proportion to their ability to cope with it."

Fox
--

Wouter Lagerweij

unread,
Apr 7, 2013, 9:16:20 AM4/7/13
to software_cr...@googlegroups.com
I can understand that performance might be a more important aspect in such an environment than elsewhere. But it still won't be above everything else. Especially in trading, making a functional mistake can have a huge financial impact. I would expect readability/maintainability of code to be of very high importance there. 
You might make some different trade-offs, but I don't think getting it fast before getting it right would be one them.

Wouter 
--
Wouter Lagerweij         | wou...@lagerweij.com

Nicholas Robinson

unread,
Apr 7, 2013, 9:17:52 AM4/7/13
to software_cr...@googlegroups.com
Going back to my original post, which is in a response to JB, Context was the point, and that while there is a general rule, one needs to know when other forces might take precedence.  I haven't stipulated bad or poor design practices to favor performance, or certainly that wasnt my intention.  Good practices, good design techniques and principles are not being contested.  In my own experience, which is neither luminary status nor accomplished, there have been many more domains than finance that require an appreciation of performance.  And in all cases good software design can absolutely be used to drive solutions in those domains, but they still require the designer to be conscious of performance right at the front as a non-functional that impacts the way things must or should be built.

Nick.

Nicholas Robinson

unread,
Apr 7, 2013, 9:26:01 AM4/7/13
to software_cr...@googlegroups.com
"You might make some different trade-offs, but I don't think getting it fast before getting it right would be one them."

The direction on where one would be taking the code would come before writing a single line of code, right or wrong, and that process is driven by a cognizance of performance.  Obviously making sure the behavior of the code is correct is a given.

Wouter Lagerweij

unread,
Apr 7, 2013, 9:38:18 AM4/7/13
to software_cr...@googlegroups.com
I can certainly see that you would take performance into account in that way. Just checking...:-) 
I have encountered a currency trading system (less performance dependent, of course) where there was a distinct lack of testing, either for performance or function... Setting that up was fun, and raised a number of architectural issues.

It would be interesting to see how these kind of performance requirements are/could be combined with a test driven way of working. Are you incorporating explicit performance testing into your build? Instrumenting the running of the tests would be useful. I haven't encountered those kind of requirements myself, so it would be great if you could share how you are dealing with that.

Wouter

Nicholas Robinson

unread,
Apr 7, 2013, 9:58:40 AM4/7/13
to software_cr...@googlegroups.com
For the stuff I am involved in, both TDD and performance testing are used Wouter.  By now we have handcrafted structures and constructs that are almost axiomatic, and they are the bedrock of most production level development - a framework if you will, though it is both a framework of coding as well as in thought.  And we have our own hand-crafted ways of stress testing our code to ensure we never falter.  In the C# space we have to contend with the managed environment, and mechanical sympathy becomes not just a deep appreciation of the hardware, but also of the meta-layer in which the code is executed. So we have a bunch of tools that we have also built to allow us to apprehend the footprints and execution envelopes of our run time code.

In all of this endeavor, we employ the very best practices that were created by some of the very best craftsman and luminaries in this group.  When the code unfolds and is beautiful, this is by standing on those shoulders; I for one never lose sight of that.  It is this knowledge that goes into even thinking about performance first.  For example some times we *know* we need to collapse an object hierarchy down and represent it more primitively - experience tells us we need to do this for the problem at hand.  That understanding came first before driving a piece of code.  And we would then use these great practices to drive towards that end solution. We dont employ cooky cutter solutions, but we have our own patterns, and we decide to work towards them first rather than later.  

A much more complex problem unfolds when simple, clean code is put into a production setting running on multiple cores, handling thousands of updates per second.  All of those areas of the code that work under normal conditions begin to buckle and get white hot.  Debugging the run time performance problems can be immensely difficult, because often it is not one single piece of code that is the problem, though when it is, thats beautiful low hanging fruit.  

J. B. Rainsberger

unread,
Apr 7, 2013, 10:06:55 AM4/7/13
to software_cr...@googlegroups.com
On Sun, Apr 7, 2013 at 12:37 AM, Nicholas Robinson <mr.nichola...@gmail.com> wrote:
 
I work in high frequency trading and options market making. I am sure we could all learn something from you too.  Before I entered this space, with over thirty years of real programming (having written my first programs at eight years old) I had the same experiences or views as your self. Its a demanding environment, thats all I can say. Do we strive for craftsman style code every single day? Yes. Do we have to focus more on performance over all else on an almost daily basis- yes. This isnt an opinion or a subjective experience; its simply a fact I myself have had to come to terms with given my own background in agile development.

In your shoes, I'd likely feel the same way. And if focusing on performance is working, then there's no real reason to do anything else. If it started to become a problem, I'd wonder:

* how often have we noticed having to actually *decrease* ease of understanding in order to improve reaction time/execution speed? Any good anecdotes?
* how often have we noticed that improving ease of understanding (by simplifying structure, for example) *improved* reaction time? Any good anecdotes?
* how often have we done something to improve reaction time which we later decided to undo to improve ease of understanding? Any good anecdotes?
* how often have we done something to improve reaction time which we later really wished you could undo to improve ease of understanding? Any good anecdotes?

Now that I've infected your subconscious with these questions, enjoy. :)
-- 

J. B. Rainsberger

unread,
Apr 7, 2013, 10:08:57 AM4/7/13
to software_cr...@googlegroups.com
On Sun, Apr 7, 2013 at 10:16 AM, Wouter Lagerweij <wou...@lagerweij.com> wrote:
 
I can understand that performance might be a more important aspect in such an environment than elsewhere. But it still won't be above everything else. Especially in trading, making a functional mistake can have a huge financial impact. I would expect readability/maintainability of code to be of very high importance there. 
You might make some different trade-offs, but I don't think getting it fast before getting it right would be one them.

I don't know the tolerances for correctness in HFT, but it seems to me that a 70% right solution that makes us €70k/day might be good enough, at least to get out the door today, since one day's profit funds a pair of people improving it for a least a month.
-- 

J. B. Rainsberger

unread,
Apr 7, 2013, 10:10:38 AM4/7/13
to software_cr...@googlegroups.com
On Sun, Apr 7, 2013 at 10:17 AM, Nicholas Robinson <mr.nichola...@gmail.com> wrote:
 
Going back to my original post, which is in a response to JB, Context was the point, and that while there is a general rule, one needs to know when other forces might take precedence.  I haven't stipulated bad or poor design practices to favor performance, or certainly that wasnt my intention.  Good practices, good design techniques and principles are not being contested.  In my own experience, which is neither luminary status nor accomplished, there have been many more domains than finance that require an appreciation of performance.  And in all cases good software design can absolutely be used to drive solutions in those domains, but they still require the designer to be conscious of performance right at the front as a non-functional that impacts the way things must or should be built.

I am guilty of, in the past, ignoring performance considerations because I knew better. I don't do that anymore, even though in most contexts, I tend to err on the side of maintainabiity over performance. When I ask a team or a pair partner to "ignore performance and focus on code health", I always, always, ALWAYS, take care to put an expiry date on that advice.
-- 

Nicholas Robinson

unread,
Apr 8, 2013, 8:02:05 AM4/8/13
to software_cr...@googlegroups.com
These four questions are very good JB; I have anecdotes for all to be perfectly honest. Thanks!


--

Sleepyfox

unread,
Apr 8, 2013, 12:14:01 PM4/8/13
to software_cr...@googlegroups.com
I'm really curious about what the performance constraint is: what is the required minimum cycle time from receipt of data input (market event) to data output (presumably an instruction to offer or buy)? What would you consider 'out of spec'?

I'm presuming that your hardware is co-lo'd with the exchange (hence the quote about 'managed service'), and that you're working with specialist, possibly even custom, network gear. We don't need to talk about SAN because everything is in memory (of course), but I'm curious about the level of analysis needed in your solution. I've seen everything from quite complex market data aggregation (rare) to the usual much simpler strategies that can be implemented in a page or two of code, often the strategies that I've seen are pre-computed leaving the actual trading to simple 'triggers'.

I find this interesting because so little is said in the broader industry (algo traders are a secretive bunch) and hence this niche which is one of the very few places that performance really does matter is also one of the least talked about.

Fox
---

Ron Jeffries

unread,
Apr 8, 2013, 12:31:28 PM4/8/13
to software_cr...@googlegroups.com
Hi Fox,

On Apr 8, 2013, at 12:14 PM, Sleepyfox <slee...@gmail.com> wrote:

I'm really curious about what the performance constraint is: what is the required minimum cycle time from receipt of data input (market event) to data output (presumably an instruction to offer or buy)? What would you consider 'out of spec'?

I am told that the requirements for speed on this kind of trading are so high as to be sensitive to the distance / time between the decision making computer and the exchange. Speed of light stuff, or nearly so.

Ron Jeffries
www.XProgramming.com
It's true hard work never killed anybody, but I figure, why take the chance?
-- Ronald Reagan



Sleepyfox

unread,
Apr 8, 2013, 12:35:20 PM4/8/13
to software_cr...@googlegroups.com
Network latency is usually uppermost in the constraint list, hence the requirement for the servers to be co-located with the exchange, you can't reduce the communication transaction overhead any more than that.

Fox
--


J. B. Rainsberger

unread,
Apr 8, 2013, 12:39:50 PM4/8/13
to software_cr...@googlegroups.com
On Mon, Apr 8, 2013 at 9:02 AM, Nicholas Robinson <mr.nichola...@gmail.com> wrote:
 
These four questions are very good JB; I have anecdotes for all to be perfectly honest. Thanks!

You're most welcome.

Can you tell us a Reader's Digest version of all those anecdotes?
-- 
Reply all
Reply to author
Forward
0 new messages