2009-02-20 18 views
42

Personalizo mucho Emacs. Recientemente, agregué algo a mi configuración de .emacs que fija esporádicamente mi CPU al 100%, pero realmente no sé de qué se trata.Consejos para perfilar portando mal Emacs Lisp?

Si presiono C-g un montón de veces, con el tiempo Voy a buscar un mensaje continuación minibuffer me pregunta si quiero guardar mis archivos de auto y luego si quiero abortar emacs por completo. Si sigo diciendo que no y presionando C-g, eventualmente podré volver a ejecutar emacs de forma normal. Una hora más tarde volverá a suceder.

Podría seguir haciendo lo mismo que yo, comentando varias cosas que he agregado recientemente, reiniciando emacs, tratando de reducir al culpable, pero va lento.

¿Hay alguna manera de que pueda perfilar emacs directamente para descubrir qué función lisp está acaparando a la CPU?

Respuesta

48

La sugerencia de establecer debug-on-quit en t para que pueda averiguar qué es lo que Emacs está haciendo es una buena idea. Puede pensar en esto como una forma de muestreo de perfiles con una sola muestra: a menudo, una sola muestra es todo lo que necesita.


Actualización: partir de la versión 24.3, Emacs contiene dos perfiladores. Hay un (nuevo) generador de perfiles de muestreo en profiler.el, y un perfilador de instrumentos (antiguo) en elp.el.

El generador de perfiles de muestreo es documented here. Es bastante fácil de usar:

Para comenzar a perfilar, escriba M-x profiler-start. Puede elegir el perfil según el uso del procesador, el uso de la memoria o ambos. Después de hacer un poco de trabajo, escriba M-x profiler-report para mostrar un búfer de resumen para cada recurso que eligió para crear un perfil. Cuando haya terminado de perfilar, escriba M-x profiler-stop.

Aquí hay un ejemplo de salida de una sesión de generador de perfiles cpu+mem con el Perforce/Emacs integration que mantengo. Expandí la función más alta (progn) para averiguar where the CPU time and memory use is coming from.

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% 

Se puede ver que el culpable es c-after-change, por lo que parece como si pudiera ahorrar mucho tiempo de CPU y de memoria por locally binding inhibit-modification-hooks to t around this code.


También puede usar el Emacs Lisp Profiler. Esto no está suficientemente documentado: deberá leer los comentarios en elp.el para obtener más información, pero básicamente ejecuta elp-instrument-package para activar la creación de perfiles para todas las funciones con un prefijo dado y luego elp-results para ver los resultados.

He aquí alguna salida típica después de escribir M-x elp-instrument-package RET c- RET, fontifying 4.000 líneas de C, y luego ejecutar elp-results (y usando elp-sort-by-function para ordenar por recuento de llamadas):

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 
... 

En su caso particular, el generador de perfiles no ayuda inmediatamente, porque no sabes qué paquete tiene la culpa. Pero si puede adivinar (o use debug-on-quit para encontrarlo con seguridad), el generador de perfiles puede ayudarlo a diagnosticar el problema en detalle.

5

Esto no es, estrictamente hablando, una respuesta a su pregunta, pero en lugar de hacer lo comment-fuera-y-reinicio, puede iniciar Emacs con la opción -q, cargar su .emacs en un búfer y evaluar cada uno de los sexpr con Cx Ce para rastrear el delincuente.

+0

Buen punto, hago eval-expression todo el tiempo, pero este modo de depuración hadn' t se me ocurrió inicialmente. – EnigmaCurry

+3

No desea evaluar cada sexp a su vez (a menos que tenga muy pocos). Use una búsqueda binaria, con 'eval-region '. – Drew

8

¿Has probado: Options->Enter debugger on Quit/C-g? (Esto es en emacs22)

Si necesita depurar puesta en marcha de emacs: utilizar emacs -q --no-site-file, visite a su .emacs (o site-start.el o lo que sea), active la opción de menú Options->Enter debugger on Quit/C-g, y luego elemento de menú Emacs-Lisp->Evaluate buffer y C-g cuando aparece congelar. Puede haber una manera más fácil de hacerlo .........

6

Con dope.el puede crear perfiles completos de .emacs o múltiples archivos elisp cargados al inicio. Descárguelo desde www.gnufans.net/~deego/pub/emacspub/lisp-mine/dope/

M-x dope-quick-start mostrará un pequeño tutorial de introducción.

Editar: La dirección URL original ya no existe, pero hay un espejo de trabajo sobre Git Hub:
https://raw.github.com/emacsmirror/dope/master/dope.el

+0

Gracias por el paquete de drogas. Pude reconfigurar mis .emacs para cargarlos en menos de un segundo usando este paquete. :) – Amjith

Cuestiones relacionadas