CLIM mail archive

[Prev][Next][Index][Thread]

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



I suppose I should supply some code with that prior post.  I also did
some further tests to clarify where the major difference is.  (All
code is compiled.) To summarize, approximately:

  .02 seconds are required to write a continuous string of length 2153 to
              *standard-output*

  2 seconds are required to indent and format this same string using my 
            indent&format to *standard-output*

  7 seconds are required to indent and format this same string using my 
            indent&format to *standard-output* to a CLIM window.

- so basic overhead of clim window is 5 seconds

  20 seconds are required to indent and format a string of similar
        length but segmented into dozens of parts with nested presentations. 

- so overhead of presentations is appx. 13 seconds. 

  27 seconds more are required to use clim indenting-output and
     filling-output instead of my home-brew on this same segmented string.

- so additional overhead of clim formatting is another 7 seconds.

This is why I'm asking for advice: I can save some time by writing my
own code but the biggest killers are presentations. How can I make
them faster?

----------------------------------------------------------------------
Now the code. In the CLIM version of formatting, the first relevant code is: 

	 (clim:stream-increment-cursor-position*
	  stream 0 *text-presentation-top-margin*)
	 (clim:indenting-output
	  (stream *text-presentation-left-margin*)
	  (clim:filling-output 
	   (stream 
	    :fill-width (list text-presentation-right-margin ':character))
	   (display-text-dispatcher
	    media parent stream graphic-x-offset graphic-y-offset selected-p)))

The dispatcher eventually reaches our own macro call:

  (present-with-display-record
   (string stream
	   :media-parent parent
	   :enclosing-x-offset x-offset
	   :enclosing-y-offset y-offset
	   :single-box *text-single-box-highlighting*)
   (display-literal-string string stream 
			   :in-selected-context in-selected-context))

Which macroexpands into:

(LET* ((DISPLAYED-ELEMENT STRING)
       (PRESENTATION-TYPE (CLIM:PRESENTATION-TYPE DISPLAYED-ELEMENT))
       (DISPLAY-OBJECT
         (IF (STRINGP DISPLAYED-ELEMENT)            ; <----- This looks
             (MAKE-INSTANCE 'STRING-DISPLAY-RECORD) ; <----- suspicious, 
             DISPLAYED-ELEMENT)))                   ; <----- but see below.
  (COND (DISPLAY-OBJECT
         (SETF (DISPLAYED-ELEMENT DISPLAY-OBJECT) DISPLAYED-ELEMENT
               (MEDIA-PARENT DISPLAY-OBJECT)      PARENT
               (DISPLAY-STREAM DISPLAY-OBJECT)    STREAM
               (PRESENTATION-TYPE DISPLAY-OBJECT) PRESENTATION-TYPE
               (ENCLOSING-X-OFFSET DISPLAY-OBJECT) X-OFFSET
               (ENCLOSING-Y-OFFSET DISPLAY-OBJECT) Y-OFFSET)
         (SETF (OUTPUT-RECORD DISPLAY-OBJECT)
               (CLIM:UPDATING-OUTPUT (STREAM)
                 (SETF (PRESENTATION DISPLAY-OBJECT)
                       (CLIM:WITH-OUTPUT-AS-PRESENTATION
                         (:STREAM STREAM
                                  :TYPE PRESENTATION-TYPE
                                  :OBJECT DISPLAY-OBJECT
                                  :SINGLE-BOX *TEXT-SINGLE-BOX-HIGHLIGHTING*
                                  :ALLOW-SENSITIVE-INFERIORS T)
                         (DISPLAY-LITERAL-STRING STRING         
                                                 STREAM
                                                 :IN-SELECTED-CONTEXT
                                                 IN-SELECTED-CONTEXT))))))
        (DISPLAYED-ELEMENT
         (CERROR "Does nothing."
                 "PRESENT-WITH-DISPLAY-RECORD: ~S, child of ~S, is not a
media-instance."
                 DISPLAYED-ELEMENT
                 PARENT))))

and where display-literal-string is

(defun DISPLAY-LITERAL-STRING (string stream &key (in-selected-context nil))
  (clim:with-end-of-page-action (:allow stream)
    (clim:with-end-of-line-action (:allow stream)
      (if in-selected-context
	  (clim:with-text-face (:bold stream)
	    (write-string string stream))
	  (write-string string stream))


OK, wondering whether our proliferate creation of display-record
instances is to blame, I removed creation and references to these
instances from the macro, without changing anything else. The
expansion is now:

(LET* ((DISPLAYED-ELEMENT STRING)
       (PRESENTATION-TYPE (CLIM:PRESENTATION-TYPE DISPLAYED-ELEMENT))
       (DISPLAY-OBJECT DISPLAYED-ELEMENT))
  (COND (DISPLAY-OBJECT
         (CLIM:UPDATING-OUTPUT (STREAM)
           (CLIM:WITH-OUTPUT-AS-PRESENTATION
             (:STREAM STREAM
                      :TYPE PRESENTATION-TYPE
                      :OBJECT DISPLAY-OBJECT
                      :SINGLE-BOX *TEXT-SINGLE-BOX-HIGHLIGHTING*
                      :ALLOW-SENSITIVE-INFERIORS T) ; no difference if nil
             (DISPLAY-LITERAL-STRING STRING
                                     STREAM
                                     :IN-SELECTED-CONTEXT
                                     IN-SELECTED-CONTEXT))))
        (DISPLAYED-ELEMENT
         (CERROR "Does nothing."
                 "PRESENT-WITH-DISPLAY-RECORD: ~S, child of ~S, is not a
media-instance."
                 DISPLAYED-ELEMENT
                 PARENT))))

I still get ...

  Elapsed Real Time = 27.08 seconds
  Total Run Time    = 27.02 seconds
  User Run Time     = 20.10 seconds
  System Run Time   = 6.92 seconds
  Process Page Faults    =          0
  Dynamic Bytes Consed   =          0
  Ephemeral Bytes Consed =  2,778,008
  There were 6 ephemeral GCs

i.e., no difference. This with CLIM's indenting/formatting. When I
changed the code to use my own indent&format function (by removing the
clim:indenting-output & clim:filling-output idiom and replacing the
write-string with my function), I'd typically get:

  Elapsed Real Time = 20.24 seconds
  Total Run Time    = 20.17 seconds
  User Run Time     = 15.52 seconds
  System Run Time   = 4.65 seconds
  Process Page Faults    =          3
  Dynamic Bytes Consed   =          0
  Ephemeral Bytes Consed =  2,116,352
  There were 4 ephemeral GCs

a savings of 7 seconds. 

Sorry if this is a lot of detail for a post, but I want to minimize
the need for iteration.
--------------------------------------------------
 Dan Suthers           | LRDC, room 505A
 suthers+@pitt.edu     | 3939 O'Hara Street
 (412) 624-7036 office | University of Pittsburgh
 (412) 624-9149 fax    | Pittsburgh, PA 15260
--------------------------------------------------

Follow-Ups: References:

Main Index | Thread Index