Reputation: 1941
In SBCL is there a way to profile functions in "COMMON-LISP" package? I'm basically looking for a way to reliably compare the run times of some built-in functions. For example, could the following function
(defun doit ()
(dotimes (i 10000000)
(make-list 10 :initial-element 0)
(list 0 0 0 0 0 0 0 0 0 0)))
be used to compare the relative efficiency of make-list
and list
, if they were profiled? (Note that the assembly code for each function is somewhat different.) My attempts at profiling in :cl bring up the low-level debugger.
Another approach using sb-ext:get-time-of-day
(presumably accurate to 1 usec) appears to give highly variable results:
(multiple-value-bind (* usec1) (sb-ext:get-time-of-day)
(dotimes (i 100000000)
(make-list 10 :initial-element 0))
(multiple-value-bind (* usec2) (sb-ext:get-time-of-day)
(dotimes (i 100000000)
(list 0 0 0 0 0 0 0 0 0 0))
(multiple-value-bind (* usec3) (sb-ext:get-time-of-day)
(- (- usec2 usec1) (- usec3 usec2)))))
Thanks for any additional advice.
EDIT: Here's another possible approach to teasing out small timing differences using the Profiler. The example again compares make-list
with list
, and produces results that are fairly reliable across multiple runs.
* (defun run-make-list ()
(dotimes (i 10000000000)
(make-list 10 :initial-element 0)))
RUN-MAKE-LIST
* (defun run-list()
(dotimes (i 10000000000)
(list 0 0 0 0 0 0 0 0 0 0)))
RUN-LIST
* (defun compare ()
(gc)
(run-make-list)
(run-list))
COMPARE
* (profile "COMMON-LISP-USER")
* (compare)
NIL
* (report)
measuring PROFILE overhead..done
seconds | gc | consed | calls | sec/call | name
----------------------------------------------------
6.532 | 0.000 | 0 | 1 | 6.532000 | RUN-LIST
6.406 | 0.000 | 0 | 1 | 6.406000 | RUN-MAKE-LIST
0.000 | 0.000 | 0 | 1 | 0.000000 | COMPARE
----------------------------------------------------
12.938 | 0.000 | 0 | 3 | | Total
estimated total profiling overhead: 0.00 seconds
overhead estimation parameters:
0.0s/call, 1.4379999e-6s total profiling, 5.98e-7s internal profiling
*
However, I'm not sure whether to believe the results. The target comparison might be swamped by the loop overhead.
Upvotes: 1
Views: 370
Reputation: 1121
SBCL has a statistical profiler, and the manual states:
You might find sb-sprof more useful than the deterministic profiler when profiling functions in the common-lisp-package, SBCL internals, or code where the instrumenting overhead is excessive.
Upvotes: 3
Reputation: 51521
You can use time
:
(time (some-form))
This runs (some-form)
and prints timing information. The results will be just as variable as those you obtained, however.
The problem is that our computers do a lot of things at the same time. Your experiment might be affected by your computer checking mail, some other process having a garbage collection, your own process having a garbage collection, the network reconnecting, phase of the moon etc.
Sometimes, you can at least make your own process have more consistent timing by starting each experiment with a (gc)
.
Upvotes: 4
Reputation: 2190
Try the time function:
(time(defun doit ()
(dotimes (i 10000000)
(make-list 10 :initial-element 0)
(list 0 0 0 0 0 0 0 0 0 0))))
Upvotes: 0