The problem is, nothing in this article even begins to address the actual criticism people have of C, instead saying that it's possible to write good C code and that Java is a memory hog. The first is true, the second is debatable, both as to whether it's the case and whether it matters.
> In a large application, a good garbage collector is more efficient than malloc/free.
My point isn't necessarily to disagree with the article, but to point out that the article has practically nothing to disagree with. It has no substance.
Yeah, the article is just praise of the minimalist C style I guess.
To elaborate, the actual problem with C is that you have to deal with ownership semantics manually. In languages with things like uniqueness typing or automatic reference counting that problem goes away. Common to all these languages and all GCed languages is the need for memory management--clearing references or maps or just generally indicating (with the language's particular idioms) its lifetime. Sometimes in a GCed language all that ownership gets untangled for you for free, but this may actually be a maintainability hazard. A trivial change might suddenly start retaining objects forever. See Haskell, where a seeming perfect program may suddenly gain space leaks upon mere removal of, say, a print statement.
Some GC implementations might be faster in practice if they can move around memory and improve cache locality and reduce fragmentation. On the other hand, some introduce long collection pauses (often an issue with C# on XNA for example), and the default malloc() on many systems is very slow and tends to fragment. But "sufficiently smart" GCs avoid these issues.
Ideally the solution is a hybrid approach: for data with obvious lifetime (bound to a scope or a certain area of the program execution) you want to actually show those intentions in the code or types. For short-lived objects that you're working with or object graphs you want garbage collection. This is what generational GC simulates, but I always find it asinine to fiddle around with references (possibly having to null out) and deal with non-deterministic deallocation when the lifetime is clear. Sigh. One day.
Every time I think about writing anything substantial in C I think about manual memory management and error handling via error codes and I quickly shelve the idea.
Any time I think about writing anything substantial in a language with exceptions, I think about non explicit exiting from my function and I quickly shelve the idea.
Zawinski's point is true iff "large application" means an application which allocates and frees plethora of tiny chunks -- however I will argue that this is not a necessity, rather a style coming from a try to port scripting experience to lower-level languages to speed up development. Probably in most cases this is not a problem (no one will notice 100us speedup in GUI), but if one starts to tweak GC or new to rescue efficiency or argue which is better, it is certainly better idea just to write it in C, with all those ugly buffers and pointers. If you already have to track memory use in your mind, why not to just take control of it?
Because then you have to control ALL of the memory, not just the data that you're interested in optimizing. Not to mention that (at least in the JVM) the gc is pretty tweakable, and the entire team may not need to know about all of the tweaks.
JWZ is an entertaining read, but unless he's updated in a post somewhere in the last 11 years, it isn't clear to me where he comes down on C at the moment.
From the "Coders at Work" interview in 2009, JWZ says that he mostly writes Perl scripts for small one-off tasks, and every now and then a new screen-saver in C.
> it isn't clear to me where he comes down on C at the moment
At the moment, his main focus seems to be his bar, so perhaps he isn't the best person to ask about the relative merits of C versus modern garbage-collected runtimes.
Not really the point, though: The point is that blanket statements about the inefficiency of gc amount to superstition, and should not just be let stand.
> for a large, complex application a good GC will be more
> efficient than a zillion pieces of hand-tuned, randomly
> micro-optimized storage management
vs:
> Note that I said a good garbage collector. Don't blame
> the concept of GC just because you've never seen a good
> GC that interfaces well with your favorite language.
Ok, so we're comparing 'state of the art GC' to 'zillion pieces of hand-tuned, randomly micro-optimized storage management'. Astoundingly, we come to the conclusion that GC Is Awesome and MOAR Efficient.
In other words, he's comparing what we're likely to get with a large C project and what we're likely to get in a modern garbage-collected environment. I don't think he's claiming more than that; where's the problem?
Having practical experience working at a company that has a large number of developers trying their stab at C, I'm bound to agree.
It's clear that you can make great code in C, if you're a good programmer and get enough time to plan things like memory management done right. Enough examples of that.
But when you don't, C is a terrible language. It is very verbose, it makes you repeat yourself and the macro system is so error-prone to the point that it's usually forbidden to use. So you have to resort to custom code generators (we have at least three!).
Most companies don't want to be in the business of worrying about buffer overflows and memory leaks and segmentation faults. They want the requested functionality implemented robustly ASAP. If there is less code to be written, there is less to test and worry about, so a high-level language that takes those concerns (largely) away is a great help.
So my advise would be to limit using C to the performance-critical parts (found using benchmarking), and only make developers work on that which understand every detail about C. Also, give them enough time to test every nook and cranny threefold.
For example, read this: http://www.jwz.org/doc/gc.html
> In a large application, a good garbage collector is more efficient than malloc/free.
My point isn't necessarily to disagree with the article, but to point out that the article has practically nothing to disagree with. It has no substance.