4 ms·
> very often it doesn't make economic sense to appease the borrow checker--there are a lot of code paths for which the overhead of a GC is just fine but lots of
by fpgaminer 5y ago
> very often it doesn't make economic sense to appease the borrow checker--there are a lot of code paths for which the overhead of a GC is just fine but lots of time spent battling the borrow checker is not fine
To me it's not about performance. A little bit of time spent now appeasing the borrow checker will pay off ten fold later when you don't have to deal with exploding memory usage and GC stalls in production.
GC is great for quick hack jobs, scripts, or niches like machine learning, but I believe at this point it's a failed experiment for anything else.
- throwaway894345 5y ago> To me it's not about performance. A little bit of time spent now appeasing the borrow checker will pay off ten fold later when you don't have to deal with exploding memory usage and GC stalls in production. I'm confused by the "it's not about performance. [reasons why it is, in fact, about performance]" phrasing, but in general a lot of applications aren't bottlenecked by memory and a GC works just fine. Even when that's not entirely the case, they often only have one or two critical paths that are bottlenecked on memory, and those paths can be optimized to reduce allocations. > GC is great for quick hack jobs, scripts, or niches like machine learning, but I believe at this point it's a failed experiment for anything else. That sounds kind of crazy considering how much of the world runs on GC (certainly much more than the other way around). I feel the need to reiterate that I'm not a GC purist by any means--I've done a fair amount of C and C++ including some embedded real time. But the idea that GC is a failed experiment is utterly unsupported.
- fpgaminer 5y ago> reasons why it is, in fact, about performance That's the story that GC sold us. History has proven it wrong. Citation: the fire hose of articles on HN about how GC bit people in the ass, and they now have to go back into their code and write a bunch of duct tape code to work around Garbage Collector Quirk #4018 de jure that results in hitching, insane memory usage, and random OOMs. > That sounds kind of crazy considering how much of the world runs on GC And much of HN runs on comments complaining about the _absurd_ amounts of memory all those non-bottlenecked applications use to do otherwise simple tasks. Or the monthly front page articles about developers and companies working to fix their otherwise straightforward, non performance critical production services that are choking themselves because the GC is going wild. I say GC is a failed experiment because it promised that programmers would be able to write code without worrying about memory. But ever since its popularization 26 years ago with the dawn of Java, coders writing in garbage collected languages have been doing nothing but worrying about memory. The experiment failed. It's time to move on. The borrow checker is an infantile incarnation of a bigger idea that is finally panning out. Rather than garbage collecting during run-time; garbage collect during compilation using static analysis. Being in its infancy it's not as easy and free to use as we'd like. But it's the path forward. And just like garbage collection before it, in the vast majority of cases, programmers don't care whether it's more or less performant. Garbage collection was vastly less performant than manual management. But it required _so_ much less developer time to build the same applications. My argument is that Rust's borrow checker, as painful as it is, results in more developer time up front, but less developer time overall when you consider the long tail of code upkeep that garbage collected applications demand. Hence my comment: "A little bit of time spent now appeasing the borrow checker will pay off ten fold later when you don't have to deal with exploding memory usage and GC stalls in production." It's not about performance; it's about saving yourself the time of having to come back to your code a month later because your TODO app is using a gig of RAM and randomly hitching.
- colejohnson66 5y ago> It's not about performance; it's about saving yourself the time of having to come back to your code a month later because your TODO app is using a gig of RAM and randomly hitching. If your GC program is using excessive RAM, that’s because of a memory leak, not the garbage collector. This can happen in C/C++ as well; just malloc/new and forget to free/delete. Last I checked, C and C++ aren’t garbage collected languages.
- throwaway894345 5y agoIt can also happen in Rust.
- wizzwizz4 5y agoIt's rarer, and you can rule it out entirely by just not using types that let you leak memory. Afaik, circular `Rc` references, `Box::leak` (and friends), `MaybeUninit` and overzealous thread spawning are the only ways of leaking memory in safe Rust.
- throwaway894345 5y agoEven if you avoid those things, how does safe Rust make leaks more rare than in a GC language? Presumably leaks in a GC language or safe Rust are almost always going to be stuff like “pushing things into a vector repeatedly even though you only care about the last item in the vector”, and clearly safe Rust doesn’t stop you from doing this any more than a GC. Note also that GC languages don’t even have the circular references case to worry about since they don’t have any need for reference counting in general.
- Filligree 5y agoLook. If I want to use two gigabytes of my users’ memory and half a core just to display a glorified IRC app, I should be allowed to do so. That’s my memory and battery capacity, not theirs.
- cdogl 5y ago
- jandrewrogers 5y agoThe situation is a bit more nuanced than this. Yes, a GC intrinsically incurs an integer factor performance cost for many codes relative to e.g. optimized C++ (I’ve optimized both). However, while ownership-based safety models are a material improvement in some cases, in other cases the borrow-checker encourages materially suboptimal software architecture e.g. in cases where ownership can only be optimally evaluated at run-time. There are other deterministic safety models often used in these cases. tl;dr: there are significant GC performance problems that a borrow-checker doesn’t solve. I can imagine cases where the performance improvement is significantly less than you might hope.
- throwaway894345 5y ago> Yes, a GC intrinsically incurs an integer factor performance cost for many codes relative to e.g. optimized C++ (I’ve optimized both) I'm guessing this performance difference isn't caused by GC but rather correlated with GC. I.e., GC langs tend to output relatively poorly-optimized code relative to the absolute beastly C/C++/Rust compilers or else idiomatic code results in objects scattered all over the heap (killing cache coherency) while idiomatic C, C++, Rust, etc tend to allocate coherent objects (objects which tend to be accessed in succession) next to each other in memory. TL;DR: No doubt a GC can be slower than manually managed memory in some cases, but it's insufficient to conclude that the entire performance gap between C/C++/Rust and Java/Go/etc is attributable to GC.
- jandrewrogers 5y agoNo, there are major classes of macro-optimizations that are impossible to implement with a GC even in theory. Some of these optimizations are idiomatic for state-of-the-art systems code. The impact on performance is integer factor.
- dw-im-here 5y agoYou're on the peak of mount stupid