Live data from Hacker News

The “C Is Efficient” Language Fallacy (2006)

scienceblogs.com

41–50 of 106 posts

Re: The “C Is Efficient” Language Fallacy (2006)

#41
This is just a variation on the "what language is best" debate, like we see here. https://news.ycombinator.com/item?id=11932675

Whilst C based apps can be made to run efficiently, its not efficient to code with the usual tools compared to other languages and IDE's (think big customer development bills), and thats even before you get into the debate of whether some code runs faster with multiple threads on multicore cpu's whilst bearing in mind the ram & bus limits, cpu cache collisions, available cpu instruction sets and so on.

More people really should get over the "awesomeness" of the clockwork turk machine, unless they are easily pleased?

Re: The “C Is Efficient” Language Fallacy (2006)

#42
post #22
post #13

Earlier quoted context omitted.

Is there a C code that can be written that compiles to assembly which is as efficient (or more) than OCaml? Likely so, and if the author doesn't even attempt to do that, I don't find their argument convincing. That is the point of the author, you certainly can achieve the same speed in C but you have to do extra work because the compiler is unable to do things like discovering the absence of aliasing. So you have to…

OK, so let's turn it around: are there cases where an expert user who wants to get the most out of the machine can generate faster code in OCaml than the fastest implementation an experienced C author can write? I don't care about the average case- I care about the maximum case (because I work on performance sensitive code).

The fastest code possible is determined by the underlying hardware and is ultimately independent of the language you use. The only reasons that you would not attain this speed limit are that you are either not aware of the best machine specific implementation, that you don't know how to express it in a given language or that a given language does not allow expressing it.

Chances are good that even really good developers are not aware of the best implementation because it might depend on pipeline latencies, constraints on which instructions can execute in parallel and so forth. That is what compilers are good at and I don't think there is an in principle difference here between C and OCaml.

The other two points are more involved. On the one hand C offers, for example, things like intrinsics and seems generally more apt to control what machine code will get generated as compared to OCaml. On the other hand C is less expressive when it comes to conveying higher level semantics to the compiler to inform its optimization decisions.

So if you are aware of the optimal implementation - which, as mentioned above, you may not be - you are in a good position with C to get (close to) the desired result if you put in the extra effort to express the semantic details. On the other hand OCaml will certainly make it harder or even impossible to express your desired machine specific implementation. But then again the OCaml compiler can use information not (easily) available from C programs to guide its optimization and could come up with a sequence of instructions better than what the developer could think of.

In principle OCaml seems to have an edge over C because of the stronger semantics making it easier for the compiler to find a good implementation possibly beating the human. On the other hand, if the compiler does a bad job and you realize it, then C probably offers you the better tools to force the compiler to honor your will.

To finally answer your question, it seems highly unlikely that there are cases where one could in principle not write a C program as fast or faster than the equivalent OCaml program. On the other hand it seems not so unlikely that a developer might not be aware of what that C code would have to look like.

Re: The “C Is Efficient” Language Fallacy (2006)

#43

An underlying point to this article that is still true is that C isn't inherently fast -- you have to work together with the compiler to make sure it generates what you want. Why is this even worth pointing out? Well, in many languages communities (Common Lisp is a good example), the speed argument comes up, and it's pointed out that carefully working with the compiler (declares in all the right places and so on) mak…

I imagine this is why so many game studios choose to use a mix of the two. C or C++ is used to write the engine code, which is kept just as simple as possible and is in charge of doing all the fiddly bits with the hardware. Unless you're on an embedded system with limited resources though (where the size of your code can actually matter) everything else is usually done in some sort of scripting language with its own reasonably fast JIT. This is possibly sub-optimal, but it enables really fast iteration on the parts of the code that need to change and go through rapid test cycles.

Deciding when to spend the energy and resources to optimize that one routine is the result of good benchmarks and code profiling. Identify your bottlenecks, and optimize the hell out of those. For everything else though, you need to ship a product, and the human effort is largely wasted on a less-called routine that makes the character blink every 173rd frame.

Re: The “C Is Efficient” Language Fallacy (2006)

#44
post #14

I'm not expert but looking at the benchmarks game data: http://benchmarksgame.alioth.debian.org/u64q/fortran.html C seems to match Fortran on about half of them and be 2 or 3x quicker on the others.

Beware of putting too much into these benchmarks. They are far too simple to say anything about larger systems. In particular, large systems are to a great extent measured in how well they optimize interactions between different modules in the system. Stuff such as link-time-optimization is not going to be shown via the rather simple benchmarks in the shootout.

Re: The “C Is Efficient” Language Fallacy (2006)

#45
The exact meaning of the statement "C is efficient" is that there is no built-in overhead: no virtual machine, no garbage collector, etc. Incidentally, the same is true for C++, with its mantra "you don't pay for what you don't use", except that there is a caveat: the mindless using of the C++ standard library classes could easily result in a significant overhead - mostly as a consequence of a liberal use of the heap for memory allocation. (But therein also lies an advantage: you could write C++ as if it was Java and still get a better efficiency.)

Re: The “C Is Efficient” Language Fallacy (2006)

#46
post #44
post #14

I'm not expert but looking at the benchmarks game data: http://benchmarksgame.alioth.debian.org/u64q/fortran.html C seems to match Fortran on about half of them and be 2 or 3x quicker on the others.

Beware of putting too much into these benchmarks. They are far too simple to say anything about larger systems. In particular, large systems are to a great extent measured in how well they optimize interactions between different modules in the system. Stuff such as link-time-optimization is not going to be shown via the rather simple benchmarks in the shootout.

Yes, but they serve as a reasonable refutation of the specific points made in the article, which focus on small, simple programs.

Re: The “C Is Efficient” Language Fallacy (2006)

#47

Mods- put a (2006) in there please. The number-crunching ecosystem has changed drastically in 10 years. He also didn't mention what compiler he's using. Intel's ICC had a huge advantage over gcc 2.95.3 (or whatever was used in '06) especially in numerical methods. (Though, I'm not sure when Intel's MKL became semi-freeware; at which point there was a significant performance jump if one opted to use the lib appropriat…

Here is the problem, it is possible to match or outperform Fortan in C++. But it is not simple. You need to use specific libraries and templates. Fortran can do this with no effort. If you're writing numeric code it is still the place to go for high performance.

Re: The “C Is Efficient” Language Fallacy (2006)

#48
If there is a universal, relatively simple formula for general efficiency, then compilers may be constructed with such algorithm to render certain language more efficient than other. Alas, there is no such thing.

Efficiency, as current situation (before true AI), are always specific. The compiler may implement certain specific optimizations that enable efficiency for certain specific applications -- inline here and there, vectorization for trivial cases, loop unwrapping for some patterns -- but hoping the compiler can work out the true efficiency is naive.

So true efficiency often requires true intelligence. I'll list one example, the famous platform specific linear algebra library blas. It is really efficient but FORTRAN is not the real reason; it is due to the human expert tweaking.

Under the context that real efficiency require human tweaking, there is some advantage of choosing C over most other language, in that C allows more room and more straight forward path for tweaking.

Comparing C against other language (not FORTRAN, which is very much like C), the efficiency of the language is achieved by its compiler doing less rather than doing more. Because the compiler is doing less, it is more straight forward on how to reach efficiency (if the coder sees the efficiency). With C, getting efficiency is programming. In comparison, for some higher level programming languages, efficiency is having faith in the language designers and compiler implementers; and tweaking often requires specific knowledge of the language and compiler. For example, knowing that using higher-order functions can be more efficient than a straight loop -- that is beyond general knowledge of programming.

On this, I would like to differentiate C from C++. C++ language (and compiler) is much more complicated than C and much of its efficiency is tweaked by the compiler. For example the '-O' flag is often not so significant for a C program but it is often day and night kind of different for a C++ program (often -O2 or even -O3 is necessary). For C++, significant portion of efficiency is dependent on the compiler, and as such, requires additional knowledge on the coder, therefore, more difficult to reach the efficiency. Of course theoretically, one can write C in C++; and many use that theory to derive that C++ is as if not more efficient than C. That is not the case in reality. Few can contain themselves in a C subset when writing C++ (if they can, why C++ instead of C?) So in reality, if you are using C++, you almost certainly are not writing C and often the efficiency path is more complicated comparing to C.

Re: The “C Is Efficient” Language Fallacy (2006)

#49

0.8 seconds for C and 2.3 seconds for C++? That discrepancy is a huge red flag in this analysis, given that the code is so naive and simple that the program should effectively be the same between C and C++, so I would expect them to have nearly identical timings.

If I read the OP correctly the benchmark used an implementation of the Longest Common Subsequence algorithm, expected to run in O(n³) time and O(n²) space. It's a dynamic programming algorithm and so not quite trivial, but, hey, it's an algorithm. The coding is never the biggest complication with those. As a benchmark it's probably OK, but language benchmarks in general are never very useful. Like, the op essentially…

If you produced the exact same binary the language that was used to produce it would be inconsequential, no?

Re: The “C Is Efficient” Language Fallacy (2006)

#50

An underlying point to this article that is still true is that C isn't inherently fast -- you have to work together with the compiler to make sure it generates what you want. Why is this even worth pointing out? Well, in many languages communities (Common Lisp is a good example), the speed argument comes up, and it's pointed out that carefully working with the compiler (declares in all the right places and so on) mak…

Except that the default, basic, recommended style for writing in C and writing in some other language X often produces very reasonably fast code in C, and horribly slow code in X. Which was the whole reason people advanced the argument that you need to use contortions to get X to generate code that even approaches the speed of normal, uncontorted C.
Post reply on HN