Функции профилирования в пакете: CL - PullRequest
1 голос
/ 11 июля 2019

В SBCL есть способ профилировать функции в пакете "COMMON-LISP"? Я в основном ищу способ надежно сравнить время выполнения некоторых встроенных функций. Например, может ли следующая функция

(defun doit ()
  (dotimes (i 10000000)
    (make-list 10 :initial-element 0)
    (list 0 0 0 0 0 0 0 0 0 0)))

использовать для сравнения относительной эффективности make-list и list, если они были профилированы? (Обратите внимание, что ассемблерный код для каждой функции несколько отличается.) Мои попытки профилирования в: cl вызывают низкоуровневый отладчик.

Другой подход, использующий sb-ext:get-time-of-day (предположительно, с точностью до 1 мксек), по-видимому, дает весьма изменчивые результаты:

(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)))))

Спасибо за любые дополнительные советы.

РЕДАКТИРОВАТЬ: Вот еще один возможный подход к выявлению небольших временных различий с помощью профилировщика. В этом примере снова сравнивается make-list с list, и результаты достаточно надежны при нескольких прогонах.

* (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
*

Однако я не уверен, стоит ли верить результатам. Сравнение целей может быть затоплено накладными расходами цикла.

Ответы [ 2 ]

4 голосов
/ 11 июля 2019

Вы можете использовать time:

(time (some-form))

Это запускает (some-form) и печатает информацию о времени. Однако результаты будут такими же переменными, как и полученные вами.

Проблема в том, что наши компьютеры делают много вещей одновременно. На ваш эксперимент могут повлиять ваш компьютер, проверяющий почту, какой-то другой процесс, имеющий сборку мусора, ваш собственный процесс, имеющий сборку мусора, повторное подключение к сети, фазу луны и т. Д.

Иногда вы можете, по крайней мере, сделать свой собственный процесс более согласованным по времени, начав каждый эксперимент с (gc).

0 голосов
/ 11 июля 2019

Попробуйте функцию времени:

(time(defun doit ()
    (dotimes (i 10000000)
      (make-list 10 :initial-element 0)
      (list 0 0 0 0 0 0 0 0 0 0))))
...