CLIM mail archive
[Prev][Next][Index][Thread]
consing of graphics operations
My question is about consing during graphics operations. I know that certain
CLIM operations, such as with-output-as-presentation will cons, but what about
drawing lines and circles? I have an application which is doing some animation
of an ongoing simulation, and I want to have the objects move from place to
place by drawing and undrawing them with +flipping-ink+.
I'm using CLIM 2.0 in Lucid on a SPARC. The code I've given below yields the
following consing measurements:
about 365 words per call to draw-circle*.
about 158 words per call to draw-line*.
about 596 words per call to draw-arrow*.
This seems awfully high to me. Is it reasonable? I can't think of why these
operations would need to cons. Is there a way to reduce the amount of consing
they do?
Thanks very much,
Scott D. Anderson
anderson@cs.umass.edu
;;; ============================================================================
;;; Code to test the amount of consing. Load the following code, turn off
;;; ephemeral GC with the function lcl:egc-off, run the doit function, and
;;; click on the test-consing menu item.
(in-package :clim-user)
(define-application-frame cons-frame ()
()
(:panes
(menu :command-menu)
(display :application
:window-class 'display-window
:incremental-redisplay nil
:display-function 'draw-display-pane)))
;;; The following methods make the format go to the lisp listener, rather than
;;; to the frame
(defmethod frame-standard-input ((frame cons-frame)) *terminal-io*)
(defmethod frame-standard-output ((frame cons-frame)) *terminal-io*)
(defmethod draw-display-pane ((application cons-frame) stream)
(window-clear stream))
(define-cons-frame-command (com-exit :menu T) ()
(frame-exit *application-frame*))
;;; ============================================================================
;;; The following is a macro to find out how much something conses.
(defmacro consing (&body body)
"Executes `body' in a way that allows consing to be measured. Returns the
number of words consed.
This uses lcl:gc-size, as shown on page 5-33 of the Lucid User's Manual.
Ephemeral GC is turned off at the beginning, if necessary, and returned to its
original state afterwards. See the functions egc-off and egc-on.
Known bugs: This macro will return weird results if a GC occurs during the
body. It seems too risky to turn off GC. This macro is best used in the body
of a compiled function, as the examples above were."
(let ((gc-on? (gensym))
(isize (gensym))
(conses (gensym)))
`(let ((,gc-on? (lcl:egc-state)))
(if ,gc-on? (lcl:egc-off))
(let ((,isize (lcl:gc-size)) ,conses)
(unwind-protect (progn ,@body)
(setf ,conses (floor (- (lcl:gc-size) ,isize) 4))
(if ,gc-on? (lcl:egc-on)))
,conses))))
;;; ============================================================================
;;; Consing is exhibited by the following command:
(define-cons-frame-command (com-test-consing :menu t) ()
(let ((pane (get-frame-pane *application-frame* 'display))
(times 100))
(multiple-value-bind (w h) (window-inside-size pane)
(setf w (round w 2)
h (round h 2))
(let ((words (consing
(loop repeat times collect nil))))
(format t "~&~d words consed in a simple loop.~%" words))
(let ((words (consing
(loop repeat times do
(draw-circle* pane w h 50 :ink +flipping-ink+)))))
(format t "~&~d words consed, or about ~f words per call to draw-circle*.~%"
words (/ words times)))
(let ((words (consing
(loop repeat times do
(draw-line* pane 0 0 w h :ink +flipping-ink+)))))
(format t "~&~d words consed, or about ~f words per call to draw-line*.~%"
words (/ words times)))
(let ((words (consing
(loop repeat times do
(draw-arrow* pane 0 0 w h :ink +flipping-ink+)))))
(format t "~&~d words consed, or about ~f words per call to draw-arrow*.~%"
words (/ words times))))))
;;; ============================================================================
(defvar *cons-frame* nil)
;;; Call this in the lisp listener
(defun doit ()
(setf *cons-frame* (make-application-frame 'cons-frame))
(run-frame-top-level *cons-frame*))
Follow-Ups:
Main Index |
Thread Index