I seem to keep doing things that drop me into the debugger with really long error messages. The amount of time it takes for the debugger to return (in Allegro anyway) seems to be proportional to the length of the output that has to be displayed in the *sldb* buffer. It can take many, many tens of seconds before the *sldb* shows up. In the meantime I have no idea what the heck is going on. To get a sense of what's happening try this:
CL-USER> (defparameter *c* (make-condition 'simple-error :format-control "foo: ~a" :format-arguments (list (loop for i from 1 to 100000 collect i))))
*C*
Then do this, hitting '0' as soon as you see the *sldb* buffer:
CL-USER> (time (with-simple-restart (abort "Bail!") (error *c*)))
I got:
; cpu time (non-gc) 750 msec user, 10 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 750 msec user, 10 msec system ; real time 8,289 msec ; space allocation: ; 805 cons cells, 2,463,904 other bytes, 0 static bytes NIL T
The I redefined format-sldb-condition in swank-allegro.lisp from:
(defimplementation format-sldb-condition (c) (princ-to-string c))
to this:
(defimplementation format-sldb-condition (c) (let ((str (princ-to-string c))) (if (> (length str) 256) (format nil "~a ..." (subseq str 0 256)) str)))
Now I try again:
CL-USER> (time (with-simple-restart (abort "Bail!") (error *c*))) ; cpu time (non-gc) 630 msec user, 0 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 630 msec user, 0 msec system ; real time 1,102 msec ; space allocation: ; 756 cons cells, 1,269,984 other bytes, 0 static bytes NIL T
~8x faster. I don't think the condition is the only thing that matters. For instance the stack frames can also be quite long. (If you inline the call to MAKE-CONDITION rather than passing a parameter to ERROR it will also be quite slow, even with my change.)
However I'm not sure if there's a good principled way to deal with this--it seems the ideal thing would be for SWANK to somehow keep more of the information on its side and send Emacs just enough to display the buffer while allowing emacs to request more information later. For example, we could stash the condition object somewhere on the connection and send emacs an abbreviated version. Then we could provide a keybinding in the *sldb* buffer that causes emacs to send a message to SWANK saying, send me the full condition now which would then be put in the appropriate place in the buffer.
Or is that crazy? If not, if someone was feeling really ambitious, maybe this could be developed into a general facility--provide a way for SWANK to send emacs an object that contains a short string and an id which emacs can then use to request a more elaborate string representation. Then on the emacs side provide a function to insert such an object into a buffer with appropriate overlays or properties or whatever to make the short string "live" so clicking on it or hitting a key while the cursor is in it causes emacs to replace it with the longer version.
-Peter
Peter Seibel peter@javamonkey.com writes:
Or is that crazy? If not, if someone was feeling really ambitious, maybe this could be developed into a general facility--provide a way for SWANK to send emacs an object that contains a short string and an id which emacs can then use to request a more elaborate string representation. Then on the emacs side provide a function to insert such an object into a buffer with appropriate overlays or properties or whatever to make the short string "live" so clicking on it or hitting a key while the cursor is in it causes emacs to replace it with the longer version.
Less ambitious people can try to tune their printer variables a bit. My settings are
*print-length* 10 *print-level* 4 *print-circle* nil
swank::*swank-pprint-length* nil swank::*swank-pprint-level* nil swank::*swank-pprint-circle* t
No, I don't see the full list, but ten elements are enough for me. If I need more details I use C-c C-p or the inspector.
Setting slime-log-events to nil is a minor speed improvement.
It may also help to set Emacs' gc-cons-threshold to a larger value than the default 400000. The error message in your example is 668857 characters long and will probably trigger one or two collections. AFAIK, Emacs' GC is not generational and a collection can take quite a while if you have many buffers open and lots of stuff loaded.
Helmut.
Helmut Eller e9626484@stud3.tuwien.ac.at writes:
Peter Seibel peter@javamonkey.com writes:
Or is that crazy? If not, if someone was feeling really ambitious, maybe this could be developed into a general facility--provide a way for SWANK to send emacs an object that contains a short string and an id which emacs can then use to request a more elaborate string representation. Then on the emacs side provide a function to insert such an object into a buffer with appropriate overlays or properties or whatever to make the short string "live" so clicking on it or hitting a key while the cursor is in it causes emacs to replace it with the longer version.
Less ambitious people can try to tune their printer variables a bit. My settings are
*print-length* 10 *print-level* 4 *print-circle* nil
swank::*swank-pprint-length* nil swank::*swank-pprint-level* nil swank::*swank-pprint-circle* t
What's controled by which set of variables?
-Peter
Peter Seibel peter@javamonkey.com writes:
What's controled by which set of variables?
The standard variables are used for almost everything. The pprint vars are only used in swank:swank-pprint, i.e., are only used for C-c C-p and the macroexpand commands.
Helmut.
Helmut Eller e9626484@stud3.tuwien.ac.at writes:
Peter Seibel peter@javamonkey.com writes:
Or is that crazy? If not, if someone was feeling really ambitious, maybe this could be developed into a general facility--provide a way for SWANK to send emacs an object that contains a short string and an id which emacs can then use to request a more elaborate string representation. Then on the emacs side provide a function to insert such an object into a buffer with appropriate overlays or properties or whatever to make the short string "live" so clicking on it or hitting a key while the cursor is in it causes emacs to replace it with the longer version.
Less ambitious people can try to tune their printer variables a bit. My settings are
*print-length* 10 *print-level* 4 *print-circle* nil
swank::*swank-pprint-length* nil swank::*swank-pprint-level* nil swank::*swank-pprint-circle* t
No, I don't see the full list, but ten elements are enough for me. If I need more details I use C-c C-p or the inspector.
Ah. I finally figured out how to make this work in Allegro. You need to do this:
(progn (tpl:setq-default *print-length* 10) (tpl:setq-default *print-level* 4) (tpl:setq-default *print-circle* nil))
-Peter