Use of the Profiler

The execution of a goal can be profiled using profile/1, which takes the goal as its argument. This will turn on the profiler, recording for each invoked predicate the number of calls, choice points created, redos tried and the predicate's callers. Counts accumulated from any previous executions of the profiler will be reset. The goal is then executed with timing information additionally monitored.

Once the goal has completed execution, the results of the execution profile can be seen by calling the show_profile_results/2 builtin predicate. The first argument to show_profile_results/2 is the display mode and is one of the atoms: by_time, by_calls, by_choice_points or by_redos. This determines how the output is sorted and what the percent figure that is printed relates to. For example, if the argument is by_time then the results are sorted according to the time spent in the predicates (in descending order) and the percentage figure is the proporation of total execution time spent executing that predicate.

The second argument gives the number of procedures to show information about, thus a value of 10 means that the top ten predicates are printed. The predicate show_profile_results/1 is equivalent to show_profile_results/2 with second argument given a value of 10 and similarly show_profile_results/0 is equivalent to show_profile_results/1 with the argument by_time.

The following example illustrates the output of show_profile_results/2:

     | ?- [chat].
     % loading file /opt/quintus/generic/q3.5/demo/chat/chat.qof
     % chat.qof loaded in module user, 0.620 sec 1,520 bytes
     
     yes
     | ?- profile(hi(questions)).
     % The profiler is switched on
     
     ...
     
     yes
     [profile]
     | ?- show_profile_results(by_time, 3).
     Proc             Calls ChPts Redos Time  % Caller(proc,cl#,cll#,%)
     user:setof/3     227   0     0     2.04  34.0
                                        user:satisfy/1,6,1 152 61.0
                                        user:seto/3,1,1 48 20.0
                                        user:satisfy/1,7,1 27 17.0
     user:satisfy/1   35738 36782 14112 0.32  5.3
                                        user:satisfy/1,1,2 13857 43.0
                                        user:satisfy/1,2,1 12137 31.0
                                        user:satisfy/1,1,1 7315 18.0
                                        user:satisfy/1,3,1 1155 6.0
     user:inv_map_l/5 4732  4732  3115  0.20  3.3
                                        user:inv_map_l/5,2,1 3115 60.0
                                        user:inv_map/4,5,1 1617 40.0
     
     yes
     [profile]
     | ?- show_profile_results(by_calls, 3).
     Proc             Calls ChPts Redos Time  % Caller(proc,cl#,cll#,%)
     user:satisfy/1   35738 36782 14112 0.32  15.3
                                        user:satisfy/1,1,2 13857 43.0
                                        user:satisfy/1,2,1 12137 31.0
                                        user:satisfy/1,1,1 7315 18.0
                                        user:satisfy/1,3,1 1155 6.0
                                        user:satisfy/1,4,1 1044 0.0
                                        user:holds/2,1,1 3 0.0
     user:database/1      13616 0     0     0.06  5.8
                                        user:satisfy/1,14,1 13616 100.0
     

The output lists the predicate name, the number of calls to that predicate, number of times a choice point was created, the number of the times the predicate was retried on backtracking and the time (in seconds) spent executing that predicate. The percentage figure depends on the display mode. In the example above 15.3% of the goal calls were to satisfy/1, but only 5.3% of the execution time was spent in satisfy/1.

Then follows the list of callers, showing for each caller the predicate name and arity, the clause number and the call number within that clause of the call (see mpg-ref-add_spypoint), followed by the number of calls made by this caller and the percentage of execution time attributed to this caller.

Notice in the example that more callers are shown for satisfy/1 when the profile results are listed by_calls than by_time. Callers that do not register any time are not listed in the output when displayed by_time. Callers are omitted in a similar way for other display modes when the relevant count is zero.

The profiler can be turned off with the noprofile/0 predicate.