CLIM mail archive


Re: CLIM philosophy wrt to X.

  Date: Fri, 30 Aug 91 13:51:26 EDT
  From: "David A. Moon" <>
  To: kanderso@BBN.COM
  Subject: Re: CLIM philosophy wrt to X. 
  Cc: Scott McKay <>, jmorrill@BBN.COM, 
  Are you sure your problem with speed of drawing in CLIM is with CLIM?
  It sounds like it's more with Lucid.  I mean that it sounds like you need
  a more optimized implementation of the present CLIM specification,
  rather than a change to the CLIM specification, to solve your problem
  with the speed of drawing lines.
  Of course passing #'draw-line* as an argument and calling it with funcall
  may be defeating optimizations you would get if you called it directly
  (such optimizations are possible, I don't claim to know whether Lucid's
  current release does them).  It defeats all inlining of the keyword
  processing and the other non-polymorphic processing it may do.

It is partly both.  In CLIM 0.9, the compiler optimizers are only defined
for Symbolics and Franz.  Since the optimization doesn't happen in Lucid, i
tried to code all my examples the same way.  My example TEST-2 is basically
the optimized case which provides about a 20% improvement.  Lucid conses
floats, and closures so a lot of the 240 bytes consed per line may be due
to Lucid (i don't have a good way to tell what got consed, so i'm not sure
who's to blame).  My TEST-3 is about a factor of 4 better than the
optimized case, since all it does is do 2 generic coordinate
transformations and call XLIB:DRAW-LINE.

Current CLIM could probably use this same technique, however if CLIM was
designed differently, it might able to get the same performance almost for
free.  For example, if the drawing option keywords were only handled by the
WITH-DRAWING-OPTIONS macro, and DRAW-LINE* took now keywords, than my
PICTURE code could look something like:

(with-output-recording-options (stream :record-p nil :draw-p t)
  ;; Setup the drawing context.
  (dotimes (x size)
    (let ((y (- size x)))
      (draw-line* stream x size y 0)  ; Draw.
      (draw-line* stream size x 0 y))))

and you could imagine that this could run about as fast as my fastest
example.  [Now that i think about it, you might be able to get about the same
performance if you had draw-line*-internal be smarter about caching the
X gcontext, which is what my code optimizes out.]

Some people may find programming this way akward, but i don't think it is
too bad since CLIM users are already wrapping lots of macros around things.
The point is, that design choices lead to different performance issues and
how well they can be handled.  The WITH-BUFFERED-OUTPUT/FORCE-OUTPUT is
another example.  I don't recommend adding another SLOT-VALUE and branch in
a lot of places that get called ALL THE TIME, if you can help it.

Besides the performance issue, while i agree it would be nicer not to worry
about buffering at all, the documentation for FORCE-OUTPUT might be simpler
than WITH-BUFFERED-OUTPUT.  It could be something like:

"Since CLIM runs on top of several window systems, it has no policy about
wheter its graphics streams are buffered or not.  On systems that buffer,
such as X, FORCE-OUTPUT can be used to make sure that all output is sent to
the graphics device.  FORCE-OUTPUT will happen automatically on any user
input to the stream."


PS.  I appreciate the CLIM spec is trying to do "the right thing", and that
building CLIM is quite hard and you can't worry about every issue all the
time.  However, i worry that my applications may die of too much of the
right thing if they can't compete performance wise with the others who
don't care as much about right or wrong.


Main Index | Thread Index