tags:

views:

130

answers:

6

I've heard many things about performance in C; casting is slow compared to normal assignments, functional call is slow, binary operation are much faster than normal operations, et cetera...

I'm sure some of those things are specific to the architecture, and compiler optimization might make a huge difference, but I would like to see a chart to get a general idea what I should do and what I should avoid to write high-performance programs. Is there such a chart (or a website, a book, anything) ?

+10  A: 

Basically, no. There is no such "tips and tricks" book from the syntax level, because there is no sure-fire guarantee that anything you stated is true (in fact, most of it is false).

In general, performance tuning should focus more on algorithms, followed by memory locality and cache optimizations. The best tools you will have are profilers (oprofile, valgrind, cachegrind, etc) followed by an understanding of machine architecture (instructions combinations which are suboptimal, alignment restrictions, memory hierarchy and size) and assembly language for your CPU (to catch less than optimal inner loop problems).

If you are interested in micro-optimizations on the Intel architecture (and all Intel compatible CPUs), this is a must read (PDF). There are more interesting guides on Agner's website.

Yann Ramin
+1 for the order of optmisations - putting algorithms first. A bad algorithm won't get fast even if it is microoptimized in each step.
Anders Abel
That's an excellent site.
Aaron H.
+1  A: 

Basically all the operations you mention are very, very fast. Unless you are doing them millions of times each second, don't worry too much about the minimal differences between the alternatives.

If you have a time critical part of your program that is running too slow, profile it to find out where exactly the time is spent and where it makes sense to optimize.

sth
+9  A: 

It seems to me that you're very confused by all this. Let's address some of these myths that you've dragged up.

Casting is slow compared to normal assignments.

That really depends on what you're casting. Between different address types, no; casting is actually free there as you're just applying a different interpretation to the same value. Casting between different widths of numeric type can be a bit slower (and sometimes is done implicitly on assignment) but is still very fast.

Function calls are slow.

Not really. They're not free, but the cost is not high enough that you should avoid them unless you've got profiling data that says otherwise. Never optimize without a very good reason to do so and proof that it will help. (For the record I've been known to revert attempted optimizations that did not have the balance of performance gains I wanted.)

Binary operations are faster than normal operations.

What's a “normal operation”? FWIW, addition is a binary operation. So is multiplication. On modern hardware, they're both pretty fast. Let the compiler worry about that. It's far more important that you focus on describing what you're doing correctly.

Now, for things that really cost:

  • I/O.
  • Memory allocation.
  • Memory copies.
  • Deeply nested (or very long) loops.

Keep your eyes on those; they're where software usually gets slow. And always pick good algorithms and data structures.

Donal Fellows
Excellent answer. Excellent. Although, heap memory allocation isn't in the same class as I/O, not even close. Heap's very fast. Not fast like a cast, but fast -- until you run low, of course. :-)
T.J. Crowder
@T.J. I/O is the slowest, and typically the hardest to actually get rid of; you're usually doing that `read()` for a good reason. Heap allocation is much faster, but you often do a lot more of it; it's not to be afraid of, but it's definitely not free.
Donal Fellows
And an area that's often needlessly costly is string handling. Poor coders often write disastrously bad code in that area because they don't keep a good handle on the memory copies and loops that are going on.
Donal Fellows
Can you clarify what you mean by "Memory Copies"? Variable assignment? memcpy? Moving one value to another? All of the above?
Aaron H.
@Aaron: All are potentially implied, but most assignments are of elemental types and so aren't a problem.
Donal Fellows
+1  A: 

Where do you hear these things?? Of all the myths that "go viral" in this field, that is possibly the most amazing one I've heard.

C is as close as you can get to machine language and still be a machine-independent "high-level" language.

All the other answers are right.

I would only add, in real software (not little two-page programs) excess generality, over-abstraction, killing flies with bazookas, are the overwhelming cause of poor performance, even though every last programmer considers his/her solution "simple".

Mike Dunlavey
+2  A: 

Once upon a time there was a book named Efficient C. Somewhat later, there was a book named Efficient C/C++ Programming: Smaller, Faster, Better. More recently still, was one named Efficient C++.

All of those cover a lot of the kinds of things that seem to interest you. The first two appear to be out of print, and the third probably should be. To remain correct and meaningful, such a chart would probably have to be updated around once a month. Almost anything you think you along such lines is probably wrong to start with, and the little that is right will probably become wrong fairly soon anyway.

Just for example, you still routinely see recommendations that if you care about performance you should avoid floating point. At one time, this was even reasonable -- but nowadays, some CPUs actually do integer math by converting the integer to floating point, doing the math, then converting the result back to an integer! Using floating point throughout can improve speed.

Jerry Coffin
A: 

I've heard many things about performance in C...

Someone has given you some very strange ideas. I especially like the distinction between "binary" and "normal" operations. I thought that for a computer, binary was normal. Someone will have to explain this distinction to me.

I would like to see a chart to get a general idea what I should do and what I should avoid to write high-performance programs.

I provide you with a chart below. It assumes you have informed yourself about the C language at the level of Kernighan and Ritchie, which is the classic textbook on C and the only C book you will ever need (although others are useful).

    Have you read Jon Bentley's book "Programming Pearls"?  --no--> read it
             |
             | yes
             V
    Have you read Peter van der Linden's book 
    "Expert C Programming: Deep C Secrets"?                 --no--> read it
             |
             | yes
             V
    Have you learned how to use valgrind --tool=callgrind
    and the kcachegrind visualizer?                         --no--> learn them
             |
             | yes
             V
    Congratulations!  You are now equipped to write 
    reasonably efficient C programs.

Most of the topics in Bentley's book, especially algorithms, are worth pursuing in greater depth elsewhere. But this chart will be a painless and entertaining way to get started.

Norman Ramsey