46 Stimmen

Tipps für die Erstellung von Profilen für Emacs Lisp mit schlechtem Verhalten?

Ich passe Emacs sehr stark an. Kürzlich fügte ich etwas zu meiner Emacs-Konfiguration hinzu, das sporadisch meine CPU auf 100 % auslastet, aber ich weiß wirklich nicht, was es ist.

Wenn ich mehrmals C-g drücke, erhalte ich irgendwann eine Meldung unter der Minipuffer, der mich fragt, ob ich meine Dateien automatisch speichern will und dann, ob ich Emacs ganz abbrechen will. Wenn ich immer wieder nein sage und die Taste C-g drücke, kann ich irgendwann wieder normal mit emacs arbeiten. Eine Stunde später oder so wird es wieder passieren.

Ich könnte so weitermachen wie bisher, verschiedene Dinge, die ich kürzlich hinzugefügt habe, auskommentieren, emacs neu starten und versuchen, den Übeltäter einzugrenzen, aber das geht nur langsam.

Gibt es eine Möglichkeit, emacs direkt zu profilieren, um herauszufinden, welche Lisp-Funktion die CPU in Anspruch nimmt?

53voto

Gareth Rees Punkte 62623

Die Anregung, die debug-on-quit a t damit Sie herausfinden können, was Emacs macht, ist eine gute Sache. Man kann sich das als eine Art Stichproben-Profiling mit einer einzigen Stichprobe vorstellen: Oft reicht eine einzige Stichprobe aus.


Aktualisierung: Beginnend mit Version 24.3 enthält Emacs zwei Profiler. Es gibt einen (neuen) Sampling-Profiler in profiler.el und einen (alten) instrumentierenden Profiler in elp.el .

Der Stichproben-Profiler ist hier dokumentiert . Es ist ziemlich einfach zu bedienen:

Um mit der Profilerstellung zu beginnen, geben Sie ein M-x profiler-start . Sie können ein Profil nach Prozessorauslastung, Speichernutzung oder beidem erstellen. Nachdem Sie etwas gearbeitet haben, geben Sie M-x profiler-report um einen zusammenfassenden Puffer für jede Ressource anzuzeigen, für die Sie ein Profil erstellt haben. Wenn Sie die Profilerstellung abgeschlossen haben, geben Sie M-x profiler-stop .

Hier ist ein Beispiel für die Ausgabe einer cpu+mem Profiler-Sitzung mit dem Perforce/Emacs-Integration die ich aufrechterhalte. Ich habe die oberste Funktion erweitert ( progn ), um herauszufinden woher die CPU-Zeit und der Speicherverbrauch kommen .

Function                                            Bytes    %
- progn                                        26,715,850  29%
  - let                                        26,715,850  29%
    - while                                    26,715,850  29%
      - let                                    26,715,850  29%
        - cond                                 26,715,850  29%
          - insert                             26,715,850  29%
            + c-after-change                   26,713,770  29%
            + p4-file-revision-annotate-links       2,080   0%
+ let                                          20,431,797  22%
+ call-interactively                           12,767,261  14%
+ save-current-buffer                          10,005,836  11%
+ while                                         8,337,166   9%
+ p4-annotate-internal                          5,964,974   6%
+ p4-annotate                                   2,821,034   3%
+ let*                                          2,089,810   2%

Sie können sehen, dass der Übeltäter c-after-change Es sieht also so aus, als könnte ich eine Menge CPU-Zeit und Speicherplatz sparen, indem ich lokal verbindlich inhibit-modification-hooks a t um diesen Code herum .


Sie können auch den Emacs Lisp Profiler verwenden. Dies ist ziemlich unterdokumentiert: Sie müssen die Kommentare in elp.el für die Details, aber grundsätzlich führen Sie elp-instrument-package um die Profilerstellung für alle Funktionen mit einem bestimmten Präfix zu aktivieren, und dann elp-results um die Ergebnisse zu sehen.

Hier ist eine typische Ausgabe nach der Eingabe von M-x elp-instrument-package RET c- RET zu erstellen, 4.000 Zeilen C zu schreiben und dann elp-results (und mit elp-sort-by-function um nach Anzahl der Anrufe zu sortieren):

Function Name                  Call Count  Elapsed Time  Average Time
=============================  ==========  ============  ============
c-skip-comments-and-strings    107         0.0           0.0
c-valid-offset                 78          0.0           0.0
c-set-offset                   68          0.031         0.0004558823
c-end-of-macro                 52          0.0           0.0
c-neutralize-CPP-line          52          0.0           0.0
c-font-lock-invalid-string     20          0.0           0.0
c-set-style-1                  19          0.031         0.0016315789
...

In Ihrem speziellen Fall hilft der Profiler nicht sofort weiter, da Sie nicht wissen, welches Paket fehlerhaft ist. Aber wenn Sie eine Vermutung anstellen können (oder mit debug-on-quit um es sicher zu finden), dann kann der Profiler Ihnen helfen, das Problem im Detail zu diagnostizieren.

8voto

luapyad Punkte 3819

Haben Sie es schon versucht? Options->Enter debugger on Quit/C-g ? (dies ist auf emacs22)

Wenn Sie den Start von emacs debuggen müssen: verwenden Sie emacs -q --no-site-file , besuchen Sie Ihr .emacs (oder site-start.el oder was auch immer), aktivieren Sie den Menüpunkt Options->Enter debugger on Quit/C-g und dann den Menüpunkt Emacs-Lisp->Evaluate buffer y C-g wenn es zu frieren scheint. Vielleicht gibt es eine einfachere Möglichkeit, dies zu tun.........

6voto

iiska Punkte 359

Mit dope.el können Sie ganze .emacs oder mehrere elisp-Dateien, die beim Starten geladen werden, profilieren. Laden Sie es herunter von www.gnufans.net/~deego/pub/emacspub/lisp-mine/dope/

M-x dope-quick-start wird eine kleine Einführungsschulung gezeigt.

Editar: Die ursprüngliche URL ist nicht mehr verfügbar, aber es gibt einen funktionierenden Mirror auf Git Hub:
https://raw.github.com/emacsmirror/dope/master/dope.el

5voto

Nietzche-jou Punkte 14185

Dies ist streng genommen keine Antwort auf Ihre Frage, aber anstatt die Sache mit dem Auskommentieren und Neustarten zu machen, können Sie emacs mit dem Befehl -q laden Sie Ihre .emacs-Datei in einen Puffer und werten Sie jeden Sexpr selbst mit C-x C-e aus, um den fehlerhaften Sexpr zu finden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X