Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Back in the "good ol' days," when we would copy shareware onto floppies for friends, we also used a fair bit of assembly. There was a common practice of "micro-optimization," where you would stare and stare at lines of assembly until you figured out a way to express it in one fewer instruction. There was even a saying, which was mathematically impossible, that "You can always remove one more instruction." Given that changing runtime performance by small constant factors isn't a major issue for (most) programming today, are programmers transferring these micro-optimization efforts elsewhere?

In other words, Can a best-practice be taken to an extreme state where it's no longer adding anything of value? And instead is wasting time?

For example: Do programmers waste time generalizing private methods that are only called from one place? Is time wasted reducing test case data? Are programmers (still) overly concerned about reducing lines of code?

There are two great examples of what I'm looking for below: (1) Spending time finding the right variable names, even renaming everything; and (2) Removing even minor and tenuous code duplication.


Note that this is different from the question "What do you optimize for?", because I'm asking what other programmers seem to maximize, with the stigma of these being "micro" optimizations, and thus not a productive use of time.

share|improve this question

closed as primarily opinion-based by gnat, Kilian Foth, MichaelT, Dan Pichelman, BЈовић Aug 25 '13 at 9:00

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

    
    
@Macneil, I do not know what other programmers micro-optimize for, but I do not have much time for that. My co-workers are busy as well (Just my 2 cents). –  Job Nov 28 '10 at 0:36
    
@Job: You've never seen someone wasting their time, changing the code for no reason? Consider yourself lucky. There are two great examples below: Variable names and minor code duplication. –  Macneil Nov 28 '10 at 0:38
1  
The question, as currently worded, is an improvement. I can't remove the close vote, but it will age away in a few days. Actually, the question is attracting some pretty good answers. –  Robert Harvey Nov 28 '10 at 4:06
1  
BTW, any best practice can be taken to such an extreme that it no longer produces value. –  Robert Harvey Nov 28 '10 at 4:27

12 Answers 12

up vote 19 down vote accepted

Code Formatting

Don't     get    me   wrong             ,
code      should be   consistent        & 
readable                                , 
but       some   take it         too far.
share|improve this answer
    
Ah yes, the good old variable types and variable names need their own columns in a series of variable declarations. Oh! Forgot the extra row for the = and the fourth for the initializers! –  Macneil Nov 28 '10 at 15:42
    
[Darn, would upvote, but my daily limit is reached...] –  Macneil Nov 28 '10 at 15:42
2  
Our professors forced us to format the code for out assignments this way. Took me years to get rid of this habit. –  Oliver Weiler Nov 28 '10 at 21:18
    
Oh dear. On other answers I was laughing, but this one really hurts :-( –  Steve314 Nov 28 '10 at 22:45
2  
+1 I once worked with a library where the developer refused to make his code const-correct because it screwed up his column-formatted code... –  Dean Harding Nov 28 '10 at 22:56

I used to write a lot of assembler back in the day. It is not just that compilers have gotten better, it is that most hardware now has lots of logic devoted to out-of-order execution of code. The real micro-issue is scheduling, most computer instructions take several machine clocks to produce a result -and a memory load that misses cache may take several hundred! So the idea was to schedule other instructions to do something useful, instead of waiting for a result. And modern machines can issue several instructions per clock period. Once we started getting out-of-order execution HW, I found that trying to get great performance with hand coding became a mugs game. First the out-of-order HW would not execute the instructions in your carefully crafted order, the fancy new HW architecture has reduced the penalty of inoptimal software scheduling enough that the compiler was usually within a few percent of your performance. Also I found out that compilers were now implementing wellknown but complexity generating tricks, such as unrolling, bottom loading, software pipelining etc. The bottom line, you have to work really really hard, skip some of these tricks and the compiler beats you. Use them all and the number of assembler instructions you need increase several fold!

Probably even more important, most performance issues, are not about instruction issue rates, but getting the data into the CPU. As I mentioned above, memory latency is now hundreds of cycles, and the CPU can execute several instructions per clock period, so unless the program -and especially the data structures are designed so that the cache hit rate is exceedingly high, microtuning at the instruction level will have no payoff. Just like military types say amateurs talk tactics, pros talk logistics. Performance programming is now more than 90% logistics (moving data). And this is hard to quantify, as modern memory management typically has multiple levels of cache, and virtual memory pages are handled by a hardware unit called the TLB. Also lowlevel alignment of addresses becomes important, as actual data transfers, are not in units of bytes, or even 64bit long-longs, but they come in units of cache lines. Then most modern machines have hardware that tries to predict which cache line misses you might need in the near future and issue automatic prefetches to get them into the cache. So the reality is that with modern CPUs performance models are so complex as to be almost un-understandable. Even detailed hardware simulators can never match the exact logic of the chips, so exact tuning is simply impossible anymore.

There is still a place for some hand coding. Math libraries (like say the exp function), as are the more important linear algebra operations (like matrix multiply) are still usually hand coded by experts that work for the hardware vendor (i.e. Intel or AMD, or IBM), but they probably only need a couple of top notch assembler programmers per mega-computer corp.

share|improve this answer
1  
+1, nice answer... –  ChristopheD Nov 28 '10 at 20:19
1  
+1 for some very interesting observations –  Gary Rowe Nov 28 '10 at 20:23
1  
Hand-coding is increasing difficult for persons working outside the CPU vendors, as the task is increasingly dependent on insider knowledge and vendor specific tools (compilers and profilers). spiral.net tries to model CPU optimization and automate the search for optimal solutions. –  rwong Nov 28 '10 at 23:51

I sometimes spend (waste?) time while choosing a good name for a variable or a method so that it is not only precisely descriptive but also has a good linguistic style.

It goes a little further when I attempt to put the entire works (a program) into the same linguistic style. Sometimes my opinion changes and I revise the book. :)

No that it takes that much time. It's rather rare. But I like to keep the good grammar in my programs.

share|improve this answer
2  
Naming is hard. Hence you should refactor a name when you think of a much better one. Note that this captures mind effort, and hopefully crystalize "why"'s too. –  user1249 Nov 28 '10 at 1:18
1  
This is very much a left-brained thing (the left side of your brain is responsible for processing language). As a right-brained programmer, I tend to spend much less time worrying about semantics and more time worrying about how all the pieces fit together. –  Jason Baker Nov 28 '10 at 2:56
6  
Variable and method naming is an important part of maintainability. One should spend time thinking about names, so that 5 years from now, the person maintaining the code has an easier time with it. –  GrandmasterB Nov 28 '10 at 3:20
    
@grandmaster: Couldn't agree more. –  Robert Harvey Nov 28 '10 at 4:09
3  
@right-brainers: Please code for the lef-tbrainers, so I can read your code also –  Juan Mendes Dec 6 '10 at 17:11

I think I've wasted weeks worth of time fiddling with Java exception handlers.

This is a lot of work for code that fails two or three times per year. Should this be a warning or an info? Error or fatal? Is it really fatal is the process will be re-spawned in five minutes? Is it really a warning if everything is still in default state?

Lots of navel gazing and discussion about the nature of an IO error. If you can't read a file over the network, is it a file error or a network error? And so on.

At one point I replaced all the concat strings with String.format so the yearly file error doesn't result in extra objects in the heap. That was a waste.

share|improve this answer
1  
This is important work. The price of failure = your error message being featured on the daily WTF. –  Steve314 Nov 28 '10 at 23:01

Time complexity. I spend way too much time optimizing things for worst case performance on a scale that is orders of magnitude larger than anything I know the program will realistically encounter.

I'm just too obsessive to let go of the 'but it could grow that big' bone, even when other design decisions preclude that from realistically happening.

However, in my defense, should the unrealistic become reality .. the optimization really isn't 'micro' any longer. Note, I didn't say impossible, but unrealistic.

Of course, requirements take precedence.

share|improve this answer
1  
I worked for a company that sank because of this. –  Henry Nov 28 '10 at 8:35
2  
@Henry - I promise, it wasn't me :) –  Tim Post Nov 28 '10 at 10:37
1  
@Henry: You mean they wasted time optimizing for things that likely would never happen, or they didn't think about things that likely would "never" happen... until they did happen and it was too late? –  Dean Harding Nov 28 '10 at 22:52
1  
@Henry: If a company has a highly scalable product and still sank, it's the sales and marketing's fault (for not targeting high-volume customers and not pricing appropriately), not the development's. –  rwong Dec 23 '10 at 6:12
    
The company spent too much time designing a system for millions of users when they didn't have 1 user. It must have been marketings fault. Yeah let's blame marketing, those guys are idiots. –  Henry Dec 24 '10 at 9:17

I suppose I am concerned with LOCs too much. Not so much LOCs themselves, but rather number of statements and even more number of duplicate statements. I am allergic to duplicate code. In general I love refactoring, but I suppose about 50% of what I do doesn't make the code signifficantly nicer.

share|improve this answer
4  
+1 for "I am allergic to duplicate code". See also my reply here: programmers.stackexchange.com/questions/14610/… –  Macneil Nov 28 '10 at 0:20
    
Thinking about it - I have this issue with loops which relates to a point Knuth made about goto, and sometimes having to trade a cycle or two or some duplicate code in order to write structured code. I will use a goto in very rare cases (most common = generated code), but my variation of this disorder is wasting time worrying and fiddling with a loop endlessly trying to eliminate a trivial inefficiency yet keep the code readable. –  Steve314 Nov 28 '10 at 22:40

Reading a file line by line instead of just reading the whole line into a string and process the string in one take.

Sure, it makes a difference in execution speed but is rarely worth the extra lines of code. It makes the code far less maintainable and increases code size.

Yes, this probably doesn't make sense if the file is 3GB big but most of the files aren't that big (at least not the ones I'm working with ;-)).

share|improve this answer
1  
Even if it is 3GB or more, a 64-bit machine can handle it with virtual memory. Use a memory mapped file and it won't even read any part of your file until it's needed. Mind you, even that's micro-optimisation in the normal case. –  Steve314 Nov 28 '10 at 22:53

When I was writing assembly language it made sense to nitpick over bytes and cycles, but that was a long time ago and compilers have come a long way since then. I wouldn't try to manually out-optimize one now.

Similarly, when I switched to writing in C it was pretty easy to do a better job than the C compilers, but every year Borland or Microsoft or someone would release a new 'n improved one that kicked the previous one around the room. I started paying attention to the actual assembly code that the compiler was emitting and, danged if it wasn't writing some nice and tight code, unrolling loops, moving variables outside the loops, etc.

Now days I'm writing in a lot higher languages like Perl, Python and Ruby. I use some of the compiler tricks up front, like loop unrolling if it makes sense, moving static variables outside the loops, etc., but I don't worry about it nearly as much because CPUs are a weeeeee bit faster now. If an app seems to be dragging unexpectedly then I'll use a profiler and see what I can find, and then if something can be improved I'll start benchmarking various ways I can think of to do something faster, and then see how it scales up.

In general I try to be smart on how I write code, based on years of experience.

share|improve this answer
    
Hi Greg, thanks for the answer, but I'm looking for what programmers do to waste time, not to optimize runtime performance. There are two great examples above: Variable names and removing even minor code duplication. –  Macneil Nov 28 '10 at 0:40

A micro-optimization: improving single-threaded performance of things that are parallelizable or that can simply be improved with new hardware.

If something is slow on a computer from 10 years ago, a cheaper solution is probably to buy a newer, faster computer, rather than to waste programmer time optimizing. A big focus of optimizations considered, though, should be finding a way to use the 8 cores you can get today, or the 64 you'll be able to get in a couple years, instead of agonizing about minutia like the extra cost of garbage collection.

share|improve this answer

In the old days when computers had clock times measured in microseconds, memory measured in kilobytes, and primitive compilers, micro-optimization made some sense.

The speed and size of current generation computers and the quality of current generation compilers mean that micro-optimization is usually a total waste of time. The exceptions tend to be when you absolutely have to get maximum performance out of some computationally intensive code ... or you are writing for an embedded system with extremely limited resources.

but I'm looking for what programmers do to waste time, not to optimize runtime performance.

Twitter and Facebook spring to mind :-)

share|improve this answer
    
Hi Stephen, that is a great commentary on micro-optimization, but do you see any modern day equivalents? [Facebook and Twitter are not "best practices" that can be carried too far.] –  Macneil Nov 28 '10 at 2:15
    
It still makes sense. The clock times might be orders of magnitude smaller, but the code is orders of magnitude larger... –  hplbsh Jan 15 '11 at 5:04
    
@Stuart - that means there's orders of magnitude more code to micro-optimize ... which simply doesn't scale. –  Stephen C Jan 20 '11 at 2:54

Micro-optimization in terms of runtime performance is hardly a closed problem even today (although it might be less common). I occasionally have to explain to people that the overhead of allocating an extra object every request or adding an extra function call is negligible.

Aside from that, I also see programmers micro-optimize for simplicity (including myself). I have yet to work somewhere that I didn't have to explain the difference between simplicity and simplism.

share|improve this answer
    
Why would programmers. be any different? What is the difference, please. –  Yar Nov 28 '10 at 4:12
    
@Yar - Why would programmers be any different from what? –  Jason Baker Nov 28 '10 at 5:35
    
why would programmers. = programmers.stackexchange.com be any different from every place that you've worked where you've had to explain the difference between these two concepts? Please explain the difference. –  Yar Nov 28 '10 at 22:15
    
@Yar - I don't know that it would. In fact, as the point of programmers.se is to help programmers pool knowledge, I would hope that it isn't so that people might be at least a little bit enlightened by my answer. –  Jason Baker Nov 29 '10 at 1:17
1  
So what's the difference b/t simplicity and simplism? –  Yar Nov 29 '10 at 16:12

I'm all for the don't-optimise-unless-really-necessary principle. And I'm all for the profile-first principle. And in principle, I will only optimise something that will make a needed difference.

That's in principle. But principle is a liar.

I have a habit of taking care with functions in frequently used libraries that I think will be used a lot in inner loops. And then, when you spot something in another function, that isn't so often used...

Oh - and then there's the "I'm writing it - of course it's an important library" logic.

Oh - and BTW. I have never yet used a profiler to guide an optimisation. Don't have access to a commercial one, and never quite built up the motivation to figure out gprof.

Basically, I'm a hypocrite. These principles apply to other people, but I have too much fear of someone saying "but why did you write it that slow and crappy way?" so I can never really apply them properly to myself.

I'm not really as bad as I make out here, though. And I'm completely immune to self-deception, so you know I'm right about that!

EDIT

I should add - one of my major stupid hang-ups is call overheads. Not everywhere, of course, but in those I-think-it'll-be-used-a-lot-in-inner-loops cases (where I have no objective evidence of a problem). I have written nasty offsetof-based code to avoid making virtual method calls more than once. The result may even be slower, since it probably isn't a style of coding that optimisers are designed to deal with well - but it's cleverer ;-)

share|improve this answer
    
+1 Ah, yes! This class parses my application's highly specific and quirky command-line arguments, but let me format and fully document it when Javadoc, because surely others will be using this for years! [Will need to upvote later, my daily cap is reached.] –  Macneil Nov 28 '10 at 15:45
    
@Macneil - that's Doxygen, I'll have you know. With every option I can find switched on, so every little function gets "documented" in excrutiating detail, complete with a dozen pretty GraphViz graphs. Really helps everyone appreciate just how important my code is - and the print-out can wallpaper quite a large office block. –  Steve314 Nov 28 '10 at 22:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.