Laziness is one of the three cardinal virtues of a programmer. In my experience thinking you know the performance characteristics of any given piece of code is always a mistake. It's certainly not true that functional idioms in general perform worse - e.g. map/reduce style can be automatically parallelized, making it more efficient on modern multicore machines than explicit loops. If you know you're writing for a specific computer you can no doubt do better by using assembly, but functional code in general is more adaptable to the unknown future, because it tends to require specifying less of the details.
Look, I am not here to say that functional programming is bad, I really enjoy using these idioms. I am just speaking from experience. Since Linq has come to C#, I see things like this in my workplace:
VeryLargeList.Select(x => x.Blah).ToArray()
And people are wondering why they get OutOfMemoryException.
Before linq, people would just loop, and the array would not have to be allocated dynamically.
All I am saying is "more abstraction may lead to performace issue, and people should be aware of it"
There's no reason that should use any more memory than an explicit loop. Maybe the particular implementation in C# does, but that's an implementation problem, not a language problem.
That's my point: the language cleanliness may obfuscate dirty implementation details, and a good developer should know what these are.
Another example, when you do this:
SuperLargeList.Where(x => x.Blah).ToArray()
There is no way for the compiler to know whether the output array will have a small size or a large size, and so it will choose one or the other assumption (dynamic vs fixed allocation). The language chooses for you how it implements things, and this is all fine as long as you know about it, and as long as you can do something about it in the case when you need to optimize.
> That's my point: the language cleanliness may obfuscate dirty implementation details, and a good developer should know what these are.
So what, we should write everything as CPU microops? A good developer should be capable of looking at that level, sure, but it shouldn't be the default; most of the time the computer is better at judging these questions than the developer.
map can only be automatically parallelized if the function has no side effects. Most languages are incapable of identifying if this is the case, so the compilers can not automatically parallelize such code.