Lots of people complain about performance reasoning in Haskell being hard, which is partially true. But mostly, IMO it is simply different from doing so in C, so you need to unlearn/relearn all your performance tweaking skills.
I don't agree. First, of all, the naive solution in C is often pretty fast, while the naive solution in Haskell often has obnoxious runtime properties.
Then, most C optimization performance reasoning applies to Haskell as well: keep your data small, in contiguous memory, etc. The first thing that complicates optimization in Haskell is that defacto Haskell data structures are the opposite: pointer/thunk-rich. So, you usually end up with libraries such as 'vector', doing the heavy lifting in the ST monad.
Then, laziness adds even more complications, both in that it adds a new class of bugs (of course, Haskell removes buffer overflows et al.) which tend to be relatively hard to debug (the heap explodes in less expected places).
When you write production code, you usually accumulate some monads. Unfortunately, the relatively obvious way to use multiple monads (monad transformers) is slow. So, you have to roll your own monad stacks:
I don't agree. First, of all, the naive solution in C is often pretty fast, while the naive solution in Haskell often has obnoxious runtime properties.
Then, most C optimization performance reasoning applies to Haskell as well: keep your data small, in contiguous memory, etc. The first thing that complicates optimization in Haskell is that defacto Haskell data structures are the opposite: pointer/thunk-rich. So, you usually end up with libraries such as 'vector', doing the heavy lifting in the ST monad.
Then, laziness adds even more complications, both in that it adds a new class of bugs (of course, Haskell removes buffer overflows et al.) which tend to be relatively hard to debug (the heap explodes in less expected places).
When you write production code, you usually accumulate some monads. Unfortunately, the relatively obvious way to use multiple monads (monad transformers) is slow. So, you have to roll your own monad stacks:
https://wiki.haskell.org/Performance/Monads
---
In the end, even something as simple as reading a list integers in the IO monad can be an exercise in frustration:
http://www.joachim-breitner.de/blog/620-Constructing_a_list_...
The same can't be claimed for C. Even a newcomer could do it.