... knowing thatI'd encountered this in Ruby profiling too, but I hadn't really identified it as a problem that needed solving. See, for example, this flat profile (from a Ruby profiler project), where
mapconsumes 20% of execution time is little help to the programmer—we need to know instead which occurrence of
mapstands for a large fraction of the time. Likewise, when one logical task is implemented by a combination of higher-order functions, then the time devoted to the task is divided among these functions in a way which disguises the time spent on the task itself. [from section 10.1]
Integer#upto(the rough equivalent of a
forloop) is at the top. The more general problem for profilers is that control flow isn't neatly nested in these languages, and this problem is worse with laziness.
In the Haskell world, solutions to problems always involve publishing a paper. Here's the overview from the GHC manual: you can annotate sections of your code with names and the profiler assigns time to those sections.