8 ms·
So every once in a while I come across old timey C optimizations in the spirit of Duff's device or bit twiddling to swap variables, 'etc 'etc... While they hav
by recuter 13y ago
So every once in a while I come across old timey C optimizations in the spirit of Duff's device or bit twiddling to swap variables, 'etc 'etc...
While they have a certain kind of charm to them they seem to be almost universally bested by increasingly mature compilers and complex (or virtualized) hardware.
So I'm kind of coming to the conclusion that clever pointer arithmetic games and even manual malloc/free are increasingly futile unless you're targeting embedded devices. If a young language like Go gets you at least in the same ballpark as C with a relatively immature GC and even toy implementations like the OP take you rather far these days... when is coding without a garbage collector even really defensible anymore?
I'm not trolling. I think pointer arithmetic is neat and the aforementioned "optimizations" are magical and possibly my generation has missed out on something wonderful. Seems it just isn't often practical to do that sort of thing anymore.
Edit: I'd like to stress that I wasn't talking in absolutes, and asking rather than telling. I'm not sure how to phrase my post better, made some edits nonetheless.
- vinkelhake 13y agoWhat you are asking for is essentially areas of computing where you want to get the most out of the hardware. Non-casual games is one such area. Some parts of finance is another. I'm not sure why you are referring to it as "games". The high-level programming you can enjoy today rely on efficient low-level implementations. You might not see them, but they are still there and still being developed.
- scott_s 13y agoSomeone has to implement those garbage-collected languages. If you ever want to be one of those someones, you need to learn manual memory management and raw-memory manipulation.
- lelandbatey 13y agoI was introduced to programming through python. Now that I'm in school, I've been doing most of my work in C++. I have to say, as much as I like programming in python, my knowledge of programming is made so much better because I've had to write C++. From an educational perspective, I think non-GC languages will always have a place (if only for teaching about computers). In production environments, I don't think that any programming practice should ever need to be "defended." Non-GC languages have their ups and downs, just as GC'ed languages have their ups and downs. Saying "it's indefensible to use one over the other" feels like saying "it's indefensible to fly somewhere instead of driving there." It doesn't make sense, since each is useful for some things and not others. Once again, when asked the question "which tool is better" my answer is "the one that's best for the job."
- MichaelGG 13y agoI think the parent comment was pointing out that less and less, there's no real reason to need C++. The performance in safer languages is usually far more than adequate, while requiring less code (less bugs) and blocking entire classes of bugs. Even Tim Sweeny of Epic (Unreal Engine) said they'd gladly switch languages to improve productivity. And game engines are one of the few places that still do need to eek out as much perf as possible. In short, something like C++ increasingly has more downs than ups. I like C, I just have seen it used in so many places where it makes the code far more verbose, introduces security holes, and has a near-negligible performance benefit.) "Best tool for the job" is misleading - some tools are nearly completely better than others. Just like globals and goto: they have uses, but less than more.
- bitwize 13y agoI once read a comment that said that C++ is like a very sharp knife. If you know how to use it, it's safer than a dull knife; if you don't, then you need to have your totin' chip taken away. I like to compare it to the F4U Corsair: anyone but a talented and experienced pilot at the yoke will lead to certain disaster. But the thing is just so powerful and so absurdly versatile that until something decisively and significantly better comes along it remains a mainstay of any halfway decent air force. A lot of people confuse being the Corsair of programming languages with being the Corvair of programming languages -- "unsafe at any speed". They're full of it. Their ignorance and lack of experience prevents them from seeing the scenarios in which the utility of C++ is absolutely indispensable.
- jules 13y agoWith C++ you trade a bit better performance for a truckload of complexity, busy work and unsafety. Whether that trade-off is worth it depends on the application, but the area in which this is a good trade-off is getting smaller and smaller. The analogy with the knife doesn't make much sense. A sharp knife is safer because you have to apply less pressure, and muscles are more precise and controlled when applying less pressure. C++ is the opposite.
- 13y ago
- dllthomas 13y agoGiven that calls to malloc aren't permitted in big swaths of the code in my current (non-embedded) job, I think it's safe to say that there are still places where GC is not appropriate.
- recuter 13y agoI never claimed otherwise, I enjoy this sort of coding but increasingly GC languages seem to be the pragmatic choice and that only makes usage like yours more precious and interesting. As that is what I was asking about I'd love for you to elaborate. :) Sorry for the confusion, I guess I could have worded my post better.
- dllthomas 13y agoHeh, fair enough. My day job is in HFT.
- pcwalton 13y agoDepends. Do you want, for example, a browser that pauses for upwards of 50 ms at a time? How about a game? Go's garbage collector can very much result in 50 ms pauses. When The Verge reviews new phones, they definitely dock points for a laggy OS, and dropping three frames in a row regularly is considered laggy these days...
- samth 13y agoThere are certainly GCs that don't pause for 50ms at a time -- Go's GC is not very good, and they even admit it. Felix Klock's PhD is an interesting exploration of this: http://www.ccs.neu.edu/home/pnkfelix/thesis/ http://www.ccs.neu.edu/home/pnkfelix/thesis/ although his collector does have some long pauses on particularly evil programs (those programs cause much longer pauses on conventional collectors).
- wtallis 13y agoSo? The fact that there are good garbage collectors doesn't save us from popular languages and runtimes with bad GCs. As long as there are people who expect to be taken seriously when they release a GC'd language with a bad GC, manual memory management should not be treated as an obsolete, obscure, or archaic skill.
- pcwalton 13y ago> There are certainly GCs that don't pause for 50ms at a time -- Go's GC is not very good, and they even admit it. Of course. I'm just refuting the specific claim of "ballpark C" performance with an immature GC.
- qznc 13y agoThere are research prototypes for such GCs and usually the performance decreases if you want time guarantees. As far as I know there is no GC, which could be used in a AAA FPS game. Convincing would be CryEngine, UnrealEngine, idTech, SourceEngine, etc starting to use a GC in their rendering, physics, sound parts.
- 13y ago
- ANTSANTS 13y agoLet me link to a (very longwinded, sorry) post I made a while back explaining how a particular type of memory pool allocator works: https://news.ycombinator.com/item?id=6176091 https://news.ycombinator.com/item?id=6176091 tl;dr if you think "manual memory management" means "malloc thing, use thing, free thing" you're kind of missing the point. Also, tricks like Duff's device and XOR swap have long since become pessimizations, not optimizations, on desktop and mobile-class hardware. Duff's device, for instance, wastes instruction cache when any decent CPU's branch predictor can eliminate most of a simple loop's overhead anyway. With the exception of manually vectorizing tight loops to take advantage of SIMD hardware (which is more of assembly's domain anyway), I think the "optimized C" of today looks pretty straightforward and unobfuscated, just with more attention paid to the details that higher level languages mostly gloss over for you. > ...and possibly my generation has missed out on something wonderful... I'm pretty certain I'm younger than you, I just grew up really wanting to make games and know how computers work. Maybe you don't need or even want to think about this kind of stuff, but it's not like the problems just magically disappeared one day. Or, more bluntly, "if C and C++ are so dumb then why isn't your browser written in Python?"
- pjmlp 13y ago> Or, more bluntly, "if C and C++ are so dumb then why isn't your browser written in Python?" Because Python's standard implementation, CPython is an interpreter?
- asveikau 13y agoI think the HN crowd honestly believes that the only reason the next browser hasn't been written in a GC language is momentum and time. That the next one will very obviously be written in Ruby or Python. I've seen discussions here to that effect. I find it hard to read HN discussions about C. One faction is totally amazed by the C equivalent of being able to tie their shoes. The other faction believes shoelaces are obsolete and everyone should wear velcro. This "my generation has missed out" thing is really odd... If you are honestly interested in it, go learn how it works! The commenter you're replying to should quit making excuses.
- 13y ago
- sehugg 13y agoFor example: It's nice to be able to write a big hunk of state to persistent store and read it back in again with a single operation (like for app pause/resume) vs. iterating through a huge object graph and serializing. Of course it'd be rad if languages could help you not screw this up (maybe Rust does?) GC doesn't solve all problems, for instance some of the weak reference bugs crop up just as often in Java as they do in Objective-C w/ ARC and ref counting.
- pjmlp 13y agoNo, but it does simplify coding a lot. In the presence of a GC many algorithms and code refactorings become much easier if you don't have to track all the time who is responsible for releasing a chunk of memory. Specially in the presence of multicore algorithms and big code bases. Added to that the fact that in today's industry developers tend to know just a little bit of the code base, given the size of some projects and team's attrition.
- inoop 13y agoI grew up on assembler, cycle counting, and computer graphics. You're right, a lot of the old-timey optimizations are not applicable on today's hardware, but this is just the march of technology. I didn't have to worry about generating graphics scanline-by-scanline like those poor Atari 2600 programmers. They didn't have to worry about instruction pairing on the Pentium though. Each generation has their tricks. As for 'manual' management, consider script engines that need to temporarily store the AST while compiling/interpreting a piece of script. These typically allocate each tree node by pointer-bumping from a large pre-allocated block of memory, and free the entire thing once done by resetting the pointer. Basically this is the same idea as a nursery in a generational collector, with the difference that you already know beforehand that you're not going to promote any of the elements. What GC algorithm is best (mark/sweep, generational, soft real-time, hard real-time) depends on your needs I guess. In that light, it's too bad MSR canned Singularity: http://research.microsoft.com/pubs/69431/osr2007_rethinkingsoftwarestack.pdf http://research.microsoft.com/pubs/69431/osr2007_rethinkings...
- pjmlp 13y ago> In that light, it's too bad MSR canned Singularity: Or that few people are aware of Oberon and Spin projects outside the respective universities. As for Singularity at least parts of the native C# (Sing#) compiler landed on the Windows Phone 8 .NET native compiler (MDIL). I would really like to know how project Midori relates to Singularity, but it is still kept internal.
- sharpneli 13y agoThe optimization tricks have merely changed, instead of the whole concept being redundant. Nowadays you should aspire to reduce branches as much as possible to keep branch prediction happy. Dependent memory accesses should be kept to a minimum. Loops should be written in a way where autovectorizer can easily convert it to a bunch of SIMD instructions. One should understand what the compiler can optimize and write code that allows it to do it's job as efficiently as possible. The same principles apply as they did in the ages gone by. There is a place for scripting languages and there is a place for heavily optimized library. It's just that the way to write those heavily optimized libraries has changed a bit. Instead of hand writing assembler one just has to write C in a way that allows the compiler to do it for you. From a web development point of view this means that in general it's good to use <insert the framework that is currently fashionable> and for the parts that require some oomph it's good to have something really optimized like ImageMagick on background. From mobile perspective it doesn't really matter in what way <It's like Yelp but for old shoes with location awareness> is written but you better hope that the basic system is optimized as much as possible. Because that transfers immediately into battery life.
- jeffdavis 13y ago"manual malloc/free are increasingly futile unless you're targeting embedded devices" Or have any algorithm that uses a lot of memory, or if you want control over how much memory the algorithm uses at a time. In the article (which is great, by the way), you can see that mark-and-sweep means scanning all of the active objects. This does not have great scalability properties. CPU gets faster, but memory gets larger, so matters won't improve over time. GCs are great for processes that are tiny. As soon as you have a memory-hungry algorithm, it starts looking worse. Also, as others have pointed out, manual memory management is not synonymous with malloc/free. There are many other choices available, and region-oriented allocators are often nice for algorithms that use a lot of memory. PostgreSQL internally uses "memory contexts" where you allocate objects with the same lifetime (e.g. transaction-local state) in the same context, and wipe it all at once.