July 15th, 2006

  • evan

time profiling

In C, constructs like "while" and "for" are built into the language. In this fascinating history of Haskell they mention that in higher-level languages (Ruby is an example, too), these control-flow constructs are built as functions in the standard libraries, which makes function-based profiling not as useful:
... knowing that map consumes 20% of execution time is little help to the programmer—we need to know instead which occurrence of map stands 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]
I'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 Integer#upto (the rough equivalent of a for loop) 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.