I m assuming the need is to discover code that takes significant time and that you could optimize to save that time. That is a different goal from just timing routines.
I m skeptical of static analyzers because everything depends on the input data mix.
Dynamic instrumentation tries to measure properties of functions, such as: self time and total time, absolute, average, and percent. Also call counts, and each routine s role in the call graph.
Dynamic instrumentation (a la gprof) has been the de-facto standard for decades, but it is very far from being the last word. For one thing, it is important to realize that most of the statistics it gives you are missing the point in terms of your original need.
These days (IMHO) you need a sampling profiler that samples the call stack, not just the program counter. It should sample on wall-clock time, not just CPU time. Samples need not be drawn at high frequency. It should suppress sampling when the app is waiting for user input. It should give you information at the line or instruction level, not just the function level. The most important statistic it should give you for a line of code is the percentage of samples containing it, because that is the most direct measure of the time that can be saved if that line is optimized.
A few profilers can do this, Oprofile and RotateRight/Zoom in particular.