[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
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))
(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.
If the flavor is known about at the time the TYPEP form is compiled,
(TYPEP <thing> '<flavor-name>) is optimized into (SI:TYPEP-FLAVOR
<thing> '<flavor-name>), which doesn't cons. The same thing is true for
DEFSTRUCT types. Your examples above were interpreted, so they didn't
get optimized. Try
(defun ship-p (s)
(typep s 'ship))
(time (progn (ship-p s) (ship-p s)) t)
In general, compiled TYPEP with a constant second argument seems to
produce good code.
I tried all the above in 7.2, but I'm pretty sure it did the same thing