CLIM mail archive


Re: reducing time overhead of text display (in 1.1)

    Date: Mon, 20 Dec 1993 14:39 EST
    From: Peter Karp <>

    >     Date: Mon, 20 Dec 1993 13:16 EST
    >     From: Peter Karp <>
    >     I also find CLIM (1.1 Lucid) text drawing to be much slower than I'd
    >     like.  Simply calling clim:draw-text* on short strings (5 characters),
    >     with each one wrapped in a different presentation, can take a couple
    >     of seconds on a Sparc 10 to display a couple hundred items.  It is
    >     this kind of marginal performance on simple tasks that makes people
    >     wonder if they should be using CLIM at all, since X applications do
    >     this kind of thing almost instantaneously.  
    > Hmm, I wasn't aware that X toolkits transparently supported
    > presentations and output recording.
    > Or if I may be less snotty, in CLIM you get output recording and
    > presentations as part of the basic functionality.  If you don't want
    > them, you have to explicitly turn them off.  So what you said is
    > definitely and apples-and-oranges comparison.

    Believe me, I appreciate CLIM's high-level capabilities or I wouldn't
    be using it.  But I believe that a measure of high-level snottiness
    has gotten in the way of getting CLIM to do simple things quickly.

I just realized something.  Part of CLIM's problem is that it is very
easy to do some things that hide a tremendous amount of complexity.
When you simply use DRAW-TEXT* to draw some text inside of a
presentation, CLIM is doing a tremendous amount of work for you.  Doing
output recording and creating presentations that magically "just work"
later is costly, but the amount of Lisp code you (the programmer) need
to write a no more code than the amount you would have to write to get
*none* of that functionality.  So when you use CLIM:DRAW-TEXT or
XLIB:DRAW-GLYPHS (or its C equivalent), it *looks* like you are doing
the same thing.  But you're not -- CLIM is doing much more work.

One could make the argument that much of Lisp is like this.

    No, X doesn't have presentations, but they certainly do have ways of
    putting text on the screen so that you can click on it that work MUCH
    faster than CLIM does (not being an X programmer (thank God) I have no
    idea how they do it).  Since I'm not a CLIM implementor, I have no
    idea why presentations are so slow, but since they only seem to be
    typed objects with a bit of info such as screen position thrown in,
    why do they take so darn long to deal with?

So with the above in mind, here's a brief answer, with some comparisons
thrown in against C/C++ as well.

 - If you're using C or C++, you are using a language most of whose
   compilers produce good code with almost no function calling overhead.
   When you are doing lots of function calling, C still beats Lisp every
   time.  CLIM does a lot of function calling.

 - Method dispatching in CLOS has to be done completely at run-time.  It
   can often be done with no overhead in C++.

 - When you say DRAW-TEXT*, here's what happens, using slower Lisp
   function calling and slower CLOS method dispatching:
   - The function DRAW-TEXT* immediately calls an :AROUND method for
     - This first makes a TEXT-OUTPUT-RECORD; note that instance
       creation can be costly on some platforms, notable MCL.  It needs
       to capture a bunchg of state from the medium to do this, such as
       the ink and text style.
     - It computes the size of the bounding box for the text; this is
       also expensive, since it involves measuring the size of each
       glyph in the text.  *** This is something that could be optimized
       if the host window system can do the work ***
     - It adds the new record to the output record tree.  Doing this
       requires recomputing the size of the parent output record, all
       the way back to the root of the output record tree.  This also
       updates the size of the scroll bar.  *** See below for a proposal
       about this ***
   - Now we enter the MEDIUM-DRAW-TEXT* method on BASIC-SHEET, which
     extracts the medium object from the sheet, and...
   - ...enters the MEDIUM-DRAW-TEXT* method for the medium, which is
     responsible for actually drawing the text.

It should come as no great surprise that calling MEDIUM-DRAW-TEXT* on
the medium (rather than the sheet or stream) is *much* faster than
calling DRAW-TEXT* and doing output recording.

WRITE-STRING can be slower in some cases, because CLIM attempts to merge
text output records together.  E.g., (progn (princ "foo") (princ "bar"))
produces a single output record instead of two of them.  Otherwise
FORMAT would produce a zillion little records.  I imagine that, in the
long run, text record merging saves time (GC, paging, etc), but it could
appear that in the short term, it is slower.  Also, WRITE-STRING and
friends need to maintain the text cursor.

    >     Are any of the  CLIM vendors putting effort into optimizing these kinds
    >     of simple operations?  I strongly advocate such work.
    > CLIM:DRAW-TEXT* wrapped in a presentation is not a "simple" operation.
    > Are you asking for an example of a sophisticated sort of output
    > record that records one big glob of text, and then rapidly generates
    > presentations on the fly so that the overhead of creating the
    > presentations is distributed over time?  That would make text output
    > faster, but it would require a more primitive level of programming to
    > use it.

    For most of our applications we don't care about big globs of text.
    We just want the operation of drawing a short piece of text (5-50
    chars) inside a presentation to be MUCH faster than it is.  I don't
    know enough about CLIM to know why this takes so long.  Perhaps it is
    the generality of all the things one can do with a presentation.  If
    users identified subsets of the complete presentation functionality,
    would that help you implement a stripped-down presentation that is

    I'll note that even drawing text with NO presentation recording seemed
    quite slow in some of my experiments of a year or two ago, apparently
    much of the time was going to CLIM's text-measurement operations.

I can believe this.

    -------- Second message --------
    Date: Mon, 20 Dec 1993 15:08 EST
    From: Peter Karp <>
    To: Scott McKay <>
    Subject: Re: reducing time overhead of text display (in 1.1)
    In-Reply-To: Your message of Mon, 20 Dec 1993 14:22 -0500

    Scott, Put another way, can we identify any common idioms of
    presentation usage?  For example, if I tell you that a common
    thing I do is create lots of presentations for really similar
    objects (e.g., 500 objects that all contain a single text string,
    and all have the same presentation type), can you come up with
    a stripped-down presentation that will handle this case faster?

There are two main strategies here:
 1) The strategy David Gadbois alluded to in which you output a very 
    small number of text strings, and then use a different strategy for
    generate presentations on the fly.  Cyc does this by spitting out
    one string, and there is a hairy translator that does its own work
    inside of TRACKING-POINTER.  The "official" way to do this would
    have been to make a new output record class, and specialize the
    MAP-OVER-OUTPUT-RECORDS-xxx generic functions to generate
    presentations on the fly.  This only works well if the text output
    looks like a bunch of paragraphs of text; it doesn't work if there
    are little disjointed bits of text all over the place.
 2) Create a new macro -- let's call it BATCHING-OUTPUT-RECORDS -- that
    delays updating the parent output records and the scroll bar.  I
    would guess that this could result in a nice *incremental* improvement,
    but it probably won't be a barnstormer.

If you can do the first of these, you can make it run like a bat out of
hell.  The second alternative may not save much time at all.  I will
investigate the second, since I have a few spare cycles right now.

Follow-Ups: References:

Main Index | Thread Index