17 ms·
mutability is a data structuring virtualization but i'd just as much suspect the runtime virtualization. that the bundle used to be 570kB isnt an immutability
by rektide 5y ago
mutability is a data structuring virtualization but i'd just as much suspect the runtime virtualization.
that the bundle used to be 570kB isnt an immutability issue. itcs that clojurescript drags in a whole clojure runtime, a new virtualization layer atop the js runtime. that, to me, is the most likely suspect.
that said, for sure, short tbeow away high gc allocation patterns are generally not good. at work there's a lot of "functional" patterns, nary a for loop in sight. this endless .map() .filter() usage causes near exactly similar issues, with shortived objects. it seems ultra sad & silly to me. waste after waste. but i also think we have much more deeply rooted problems.
- jdlshore 5y agoAre you sure about the short-lived allocations being a problem for the collector? My understanding of modern generational garbage collectors was that they performed quite well with short-lived garbage. Not as well as not creating the garbage in the first place, of course, but not so badly as to be a problem in most cases.
- ncmncm 5y ago"Perform quite well" is always relative to some reference. The oldest trick in the book is comparing to something even slower and saying "see? fast!". GC apologists seek to normalize this behavior. They often succeed, at that. Performing quite well against actually fast things, less often.
- jdlshore 5y agoYou seem to have an axe to grind. Performance isn’t black and white. Optimizing your memory usage isn’t going to do you a whit of good if you’re constrained by your database queries. Optimizing your DB queries isn’t going to do you any good if you’re constrained by a chatty microservice architecture. Optimizing your UI response time isn’t going to do you any good if you’re already below the threshold of perceived speed. Etc. GC performance on short-lived objects is quite good in enough situations to matter, such that optimizing for it, rather than your application architecture, is likely foolish outside of performance sensitive loops. Time is always limited. Spending your optimization budget on micro-optimizations is short-sighted.
- ncmncm 5y agoMeaningless personal criticisms undermine your argument. Performance problems usually appear in places we prefer they would not, often runtime apparatus we poorly control such as GC. It is always preferable to try to ignore and discount those, as they may be arbitrarily hard to fix, so people do. Yet, actually not depending on such apparatus, where it is the problem, gets you free optimization. Performance doesn't care where it is found or lost. Micro-optimization is foundational; fail there, and there is often little else you can usefully do. The best optimizations are not doing the thing at all. GC is always strictly worse than no memory management. Fixing your chatty microservoices and your under- or over-indexed DB queries may do you no good if you have built in bottlenecks of your own. "Quite good" means nothing except in comparison to something else.
- nyanpasu64 5y agoI want a world without garbage collection. I don't think we can achieve a world without garbage collection while there are codebases based around aliased pointers (which makes lifetime reasoning difficult, and causes enough use-after-frees to make the Linux desktop apps I use unstable, unless you use refcounting) and circular references (which is difficult to refcount). Maybe I'll wait for Rust programmers to rewrite software around tree-based ownership (restrictive but immune to these problems) and ECS/arena indexes (can use-after-free but won't segfault). In the time being, while "spiderweb object graphs" are commonplace, perhaps Nim's memory management (https://nim-lang.org/docs/gc.html https://nim-lang.org/docs/gc.html) can give us "non-GC by default, refcounting or GC when necessary". I want it to succeed. I hope it does.
- meheleventyone 5y agoThis is true for small amounts of garbage but not for large amounts which is still slow and large is relative to the hardware your user is running on. It’ll also cause a death by a thousand cuts where it’s extremely difficult to dig yourself out of poor performance because the cause runs throughout the program. It’s better to look at cheap short lived collection as a great way to get the thing you’re making working but ultimately something that needs to be cleaned up to be production ready.
- cryptonector 5y agoImmutability is a drag if you create lots and lots of referenced state because, e.g., you want to hold on to many snapshots of past state. Immutability done right need not be much worse than mutability. For example, jq's internal value representation is immutable in appearance: - mutations yield new values, - but when the value being "mutated" has only one extant reference then mutation is done in-place, - while when the value being "mutated" has more than one extant reference then mutation is done by copy-on-write. If you manage to always have extra references, then "immutable mutation" gets expensive. If you manage hold on to old references for a long time, then "immutable mutation" gets even more expensive. In a run-time with a GC not based on reference counting you do have to GC all the intermediate garbage. Immutable data structures really lend themselves well to reference counting GCs because you can't have cycles in immutable data.
- fnordsensei 5y ago> Immutability is a drag if you create lots and lots of referenced state because, e.g., you want to hold on to many snapshots of past state. Isn't it the opposite? If you want to hold on to many referenced states at the same time, an immutable data structure should provide less overhead than a mutable one, due to structural sharing.
- cryptonector 5y agoA performance drag. Let's say you have an app that for N inputs creates N^2 state in memory... But now, if that's just what you must do for some reason, then, yes, immutability makes the task of taking all those snapshots real easy.
- cryptonector 5y agoI should add that reference counting GCs are nice because short-lived garbage is freed immediately and there's no need to look for garbage, so they're much faster than scanning GCs. Reference counting GCs can have GC-like pauses when releasing objects that have singular references to many many many other objects, but the same is true in manual memory management systems.
- casion 5y agoClojure solves these issues with unneeded garbage creation in algorithms with the transducers functions. And you can of course just use java objects whenever you want.