4 ms·
Yeesh... this is why it's good to have some experience with a language where you have to manage your own memory, even if you only write JavaScript at your day
by _bxg1 7y ago
Yeesh... this is why it's good to have some experience with a language where you have to manage your own memory, even if you only write JavaScript at your day job. To anyone who's written C++ before this difference is incredibly obvious.
- _bxg1 7y agoAs a rule of thumb: anything done in a pure-functional/immutable style is probably going to take a performance hit. This tradeoff is often worth it for maintainability, especially if you're using true immutable data structures like Immutable.js or Clojure's structures which reduce copying to the absolute minimum. But always be aware of this tradeoff. If you're doing a simple operation over 15,000 of anything, just use a for loop for goodness' sake.
- bakhy 7y agoI don't know if this works well on JS, but there is a purely functional way that avoids most of the performance hit - generator methods. In C#, I'd write functions that return IEnumerable<T>, using yield return, and others that combine them with LINQ's Concat, and aside from many iterator objects, only one big array would need to be allocated. When it happens that parts of this work later turn out not to be needed, it's easy to discard an enumerable, and the iteration is not actually performed. It can sometimes lead to really ellegant code that also performs well.
- awinder 7y agoIs there an equivalent for "just use a for loop" if you are in some immutableland though? This has always confused/worried me watching that space -- maybe you're fundamentally restructuring problems in FP to avoid these situations but to my eyes it looks like a world of newly-invented scaling issues.
- _bxg1 7y agoImmutable data structures let you use pure-functional patterns without most of the associated costs. The OP's original strategy would work just fine with immutable structures.
- kuu 7y ago> just use a for loop for goodness' sake. Unless you're on Python... /s
- barrkel 7y agoIt really depends, I wouldn't be so forthright. In more complex apps, mutable structures may be shared with other bits of code, and you may end up copying for safety rather than because immutability forces you to. Non-local reasoning is less reliable as complexity and team size (concurrent development!) scales up, and the rules you adopt to ensure development can scale with larger teams can hit you on the other side. This is a distinct issue from the maintainability argument. I'm saying that if you don't have functional code throughout, you might end up copying more often than you think. Immutability means you can hang on to things and share them with confidence. For example, consider a method which returns an array in Java or C# or some other language without type-based constness. It's not safe to cache that and return the cached instance, because the array is mutable. So almost invariably such arrays are constructed afresh every time - copying induced by lack of immutable style.
- _bxg1 7y ago> I'm saying that if you don't have functional code throughout, you might end up copying more often than you think. Immutability means you can hang on to things and share them with confidence. But if you need to copy you're still following an "immutable" pattern: needing to share data with the guarantee that it won't be changed. Copying is just a very blunt way of accomplishing that. Immutable data structures will of course be a big improvement over simple copying whenever you need to do this sort of thing, but if you can avoid it altogether by modifying things in place instead of relying on their lack of mutation, you'll have even less overhead. Clojure's transients, for example, were created for exactly this purpose: https://clojure.org/reference/transients https://clojure.org/reference/transients