Hacker News new | ask | show | jobs
by DeathArrow 604 days ago
I don't know how things are implemented in other languages but in C# 9, these operations are optimized.
3 comments

There are ways to keep functional transformations and immutable data structures efficient. Copy-on-write, unrolling expressions into loops, etc. Proper functional languages have them built into the runtime - your clean map-reduce chain will get translated to some gnarly, state-mutating imperative code during compilation. In non-FP or mixed-paradigm languages, where functional building blocks are just regular library functions (standard or otherwise), map-reduce is exactly what it says on the tin - two loops and a lot of copying; you want it fast, you have to mostly optimize it yourself.

In other words, you need to know which things in your language are considered to be language/compiler/runtime primitives, and which are just regular code.

Most languages don't have these facilities at all - so you need to be really careful what you are doing. This works "fine" with test data, because your test data usually is a few hundert items max. A few years back people at our firm build all data filtering in the frontend, to keep the "backend clean". That worked fine in testing. In production with 100k rows? Not so much.

Even in C# it depends on the linq provider - if you are talking to a DB, your quers should be optimized. Linq to objects doesn't do that and repeated scanning can kill your performance. E.g. repeated filtering on large lists.

I am talking about IEnumerable, not IQueryable: https://blog.ndepend.com/net-9-0-linq-performance-improvemen...
Are they? LINQ is usually slower than for loop
Quite often it compiles to the same IL. Would you like to provide some godbolt examples where it's significantly different?
IL is always different since it's a high-level bytecode. The machine code output is different too. Now, with guarded devirtualization of lambdas, in many instances LINQ gets close to open-coded loops in performance, and it is very clever in selecting optimal internal iterator implementations, bypassing deep iterator nesting, having fast-paths for popular scenarios, etc. to achieve very good performance that can even outperform loops that are more naive, but unfortunately we're not there yet in terms of not having a baseline overhead like iterators in Rust. There is a selection of community libraries that achieve something close to this, however. I would say, LINQ performance today gets as close as it can to "it's no longer something to be worried about" for the vast majority of codebases.
Two or so years ive been developing library and i remember where switching from something simple like First or FirstOrDefault to for loop made difference when using benchmark dotnet

Then I found that it was common knowledge that linq is slower, even among ppl on c#s discord