1
votes

Fonctions de profilage dans le package: CL

Dans SBCL, existe-t-il un moyen de profiler les fonctions dans le package "COMMON-LISP"? Je cherche essentiellement un moyen de comparer de manière fiable les temps d'exécution de certaines fonctions intégrées. Par exemple, la fonction suivante

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

pourrait-elle être utilisée pour comparer l'efficacité relative de make-list et list , si elles ont été profilées ? (Notez que le code d'assemblage pour chaque fonction est quelque peu différent.) Mes tentatives de profilage dans: cl font apparaître le débogueur de bas niveau.

Une autre approche utilisant sb-ext: get-time- of-day (vraisemblablement précis à 1 usec) semble donner des résultats très variables:

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

Merci pour tout conseil supplémentaire.

EDIT : Voici une autre approche possible pour éliminer les petites différences de synchronisation à l'aide du profileur. L'exemple compare à nouveau make-list avec list et produit des résultats assez fiables sur plusieurs exécutions.

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

Cependant, je ne suis pas sûr de croire aux résultats. La comparaison cible peut être submergée par la surcharge de la boucle.


1 commentaires

avez-vous recherché une fonctionnalité de temps CL standard?


3 Réponses :


0
votes

Essayez la fonction de temps:

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


1 commentaires

qui chronométrerait la durée d'une définition, pas l'exécution



4
votes

Vous pouvez utiliser time:

(time (some-form))

Cela exécute (sous une forme) et imprime les informations de synchronisation. Cependant, les résultats seront tout aussi variables que ceux que vous avez obtenus.

Le problème est que nos ordinateurs font beaucoup de choses en même temps. Votre expérience peut être affectée par le fait que votre ordinateur vérifie le courrier, un autre processus ayant un ramasse-miettes, votre propre processus ayant un ramassage des ordures, la reconnexion du réseau, la phase de la lune, etc.

Parfois, vous pouvez au moins rendre votre processus plus cohérent en commençant chaque expérience avec un (gc).


1 commentaires

Le profileur SBCL est-il en mesure d'éviter une partie de la variation d'arrière-plan pour les fonctions définies par l'utilisateur et le profileur est-il applicable aux fonctions CL intégrées?



2
votes

SBCL dispose d'un profileur statistique et le manuel indique:

Vous pourriez trouver sb-sprof plus utile que le profileur déterministe lors du profilage des fonctions dans le package common-lisp, des composants internes SBCL ou du code où la surcharge d'instrumentation est excessive.


0 commentaires