0

The Time Profiler can measure the amount of time spent on certain methods. Is there a similar method that measures the number of times a method is called?

Paul Alexander
  • 31,970
  • 14
  • 96
  • 151

1 Answers1

4

DTrace can do this, but only in the iPhone Simulator (it's supported by Snow Leopard, but not yet by iOS). I have two writeups about this technology on MacResearch here and here where I walk through some case studies of using DTrace to look for specific methods and when they are called.

For example, I created the following DTrace script to measure the number of times methods were called on classes with the CP prefix, as well as total up the time spent in those methods:

#pragma D option quiet
#pragma D option aggsortrev

dtrace:::BEGIN
{
    printf("Sampling Core Plot methods ... Hit Ctrl-C to end.\n");
    starttime = timestamp;      
}

objc$target:CP*::entry
{
    starttimeformethod[probemod,probefunc] = timestamp;
    methodhasenteredatleastonce[probemod,probefunc] = 1;
}

objc$target:CP*::return
/methodhasenteredatleastonce[probemod,probefunc] == 1/
{
    this->executiontime = (timestamp - starttimeformethod[probemod,probefunc]) / 1000;
    @overallexecutions[probemod,probefunc] = count();
    @overallexecutiontime[probemod,probefunc] = sum(this->executiontime);
    @averageexecutiontime[probemod,probefunc] = avg(this->executiontime);
}

dtrace:::END 
{
    milliseconds = (timestamp - starttime) / 1000000;
    normalize(@overallexecutiontime, 1000);
    printf("Ran for %u ms\n", milliseconds);
    printf("%30s %30s %20s %20s %20s\n", "Class", "Method", "Total CPU time (ms)",  "Executions", "Average CPU time (us)");
    printa("%30s %30s %20@u %20@u %20@u\n", @overallexecutiontime, @overallexecutions, @averageexecutiontime);
}

This generates the following nicely formatted output:

        Class                         Method  Total CPU time (ms)           Executions Average CPU time (us)
      CPLayer                -drawInContext:                 6995                  352                19874
       CPPlot                -drawInContext:                 5312                   88                60374
CPScatterPlot      -renderAsVectorInContext:                 4332                   44                98455
CPXYPlotSpace        -viewPointForPlotPoint:                 3208                 4576                  701
       CPAxis               -layoutSublayers                 2050                   44                46595
CPXYPlotSpace -viewCoordinateForViewLength:linearPlotRange:plotCoordinateValue:                 1870                 9152
...

While you can create and run DTrace scripts from the command line, probably your best bet would be to create a custom instrument in Instruments and fill in the appropriate D code within that instrument. You can then easily run that against your application in the Simulator.

Again, this won't work on the device, but if you just want statistics on the number of times something is called, and not the duration it runs for, this might do the job.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
  • Brad Larson - you say: "your best bet would be to create a custom instrument in Instruments and fill in the appropriate D code within that instrument" - how would I do that? Instruments complains about syntax errors when I do... – shmim Apr 02 '15 at 21:35
  • Specifically, how would I enter your script above, which looks like it will do exactly what I want :-) – shmim Apr 02 '15 at 21:51
  • Haha, somebody else struggled with this - two years ago: http://stackoverflow.com/questions/17925261/custom-instruments-how-to-output-aggregations-like-dtrace-script – shmim Apr 02 '15 at 22:14
  • 1
    @shmim - I've replaced the links with archived ones, because they've had problems keeping the site up. Used to be a good, solid resource, but time hasn't been kind to it. As far as setting up the custom instruments, it's possible they've changed how these are done in the last five years, but the second link shows how you used to be able to take the above and turn it into a custom instrument. The above is a full DTrace script that runs at the command line, and can't be taken word-for-word into an instrument. – Brad Larson Apr 02 '15 at 23:05
  • Wonderful! These articles are fantastic and having them easier to find will be terrific for anyone looking for info on DTrace! Thanks! – shmim Apr 03 '15 at 00:40
  • Here's a followup - I've got `@overallexecutions[probemod,probefunc] = count()` running within the probe. How would I access the value of the `@overallexecutions` aggregator and display it in Instruments? I've messed around with the `copyinstr` and `copyin` subroutines mentioned in Apple's docs, but to no avail... – shmim Apr 03 '15 at 01:09