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

(typep <instance>)

In general, the evaluator is less efficient than compiled code.  These
inefficiencies can include consing, as in your example.  Note that your
exact example, if compiled, causes no consing.

  (compile (defun test (s) (progn (typep s 'ship) (typep s 'ship))))
  (time (test s) t)
  Evaluation of (TEST S) took 0.000205 seconds of elapsed time including:
    0.001 seconds processing sequence breaks,
    0.001 seconds in the storage system (including 0.000 seconds waiting for pages):
      0.001 seconds processing 1 page faults including 0 fetches,
      0.000 seconds in creating and destroying pages, and
      0.000 seconds in miscellaneous storage system tasks.

Note that if you compile the function TEST above before you define the
flavor SHIP, you get the following warning:

  For Function TEST
    An error occurred while running optimizer CLI::TYPEP-OPTIMIZER on (TYPEP S 'SHIP): 
    SHIP is not a known type.

Here the compiler is telling you that it can't generate as efficient
code as it would like.  Admittedly, the warning's wording is not all
that great.

In summary, to improve your performance (1) compile your code, and (2)
fix things which generate compiler warnings.

    Date: Tue, 31 May 88 17:24 PDT
    From: Jerry@MARLOWE.inference.dialnet.symbolics.com (Jerry Bakin)

    An application I am involved with has a simple process wait function:
    It iterates over the elements of an array, and if the element is of the
    appropriate type (a session), that element is sent a :poll message.

    Because the elements of the array can be nil, a keyword, or an object;
    the iteration is driven off the results of (typep ....)

    While we were timing various portions of the System, we discovered
    thousands of conses of (INSTANCE SESSION) formed every second!

    We traced these conses to the call to typep!

    For instance, try the following:

    (defflavor ship () ())
      (setf s (make-instance 'ship))
    #<SHIP 10302715>
      (time (progn (typep s 'ship) (typep s 'ship)) t)

    Evaluation of (PROGN (TYPEP S #) (TYPEP S #)) took 0.001267 seconds of elapsed time
    including 0.000 seconds waiting for the disk for 0 faults.
    4 list words consed in WORKING-STORAGE-AREA.
    Consed in list region of WORKING-STORAGE-AREA:

    These conses are actually created by a call to cli::type-expand.

    Now I imagine these conses will be caught by the ephemeral garbage
    collector, but I wonder if they are required at all!

    I am not looking for stop gap solutions; there are several ways of
    eliminating the call in this case.  I would like to see typep itself
    fixed or at the very least documented in this inefficiency.