#67: initarg checking performance -------------------------+-------------------------------------------------- Reporter: ehuelsmann | Owner: somebody Type: defect | Status: new Priority: major | Milestone: Component: CLOS | Version: Keywords: performance | -------------------------+-------------------------------------------------- Our initarg checking strictness has improved (used to be non-existent), but we've seen a rather large performance hit, amongst other things upon object instantiation (make-instance).
Functions involved (?):
ALLOCATE-INSTANCE INITIALIZE-INSTANCE REINITIALIZE-INSTANCE SHARED-INITIALIZE UPDATE-INSTANCE-FOR-DIFFERENT-CLASS UPDATE-INSTANCE-FOR-REDEFINED-CLASS
#67: initarg checking performance --------------------------+------------------------------------------------- Reporter: ehuelsmann | Owner: somebody Type: enhancement | Status: new Priority: major | Milestone: unscheduled Component: CLOS | Version: Resolution: | Keywords: performance --------------------------+------------------------------------------------- Changes (by ehuelsmann):
* type: defect => enhancement * milestone: => unscheduled
#67: initarg checking performance --------------------------+------------------------------------------------- Reporter: ehuelsmann | Owner: somebody Type: enhancement | Status: new Priority: major | Milestone: unscheduled Component: CLOS | Version: Resolution: | Keywords: performance --------------------------+-------------------------------------------------
Comment(by ehuelsmann):
CHECK-INITARGS is called from:
* MAKE-INSTANCE-STANDARD-CLASS * ENSURE-CLASS * MAKE-INSTANCE * UPDATE-INSTANCE-FOR-DIFFERENT-CLASS * UPDATE-INSTANCE-FOR-REDEFINED-CLASS
It computes its return value based on the applicable methods from SHARED- INITIALIZE, INITIALIZE-INSTANCE and the class's slot definitions. The applicable methods are computed using the instance and the shared- initialize-param.
The above means that we should probably calculate all valid initargs from both the applicable methods and the slots, testing the initargs to be members of the union.
#67: initarg checking performance --------------------------+------------------------------------------------- Reporter: ehuelsmann | Owner: somebody Type: enhancement | Status: new Priority: major | Milestone: unscheduled Component: CLOS | Version: Resolution: | Keywords: performance --------------------------+-------------------------------------------------
Comment(by ehuelsmann):
I was confused for a moment, so recording the outcome here now that I'm not confused anymore:
Even though the computation of the applicable methods for SHARED- INITIALIZE and INITIALIZE-INSTANCE takes the values of the initargs, there's only a single parameter to be dispatched on in the latter case (the instance itself) and two parameters in the former case (the instance itself and the slot-names parameter).
This means INITIALIZE-INSTANCE and SHARED-INITIALIZE can have a shared cache of valid initargs, keyed on the class of the instance and the value of slot-names being (EQ NIL)/(EQ T)/CONS. The cache is invalidated by redefinition of any one of the superclasses of the instance-class (or of the class itself) or a defgeneric/defmethod on INITIALIZE-INSTANCE or SHARED-INITIALIZE concerning any one of those classes.
#67: initarg checking performance --------------------------+------------------------------------------------- Reporter: ehuelsmann | Owner: somebody Type: enhancement | Status: new Priority: major | Milestone: unscheduled Component: CLOS | Version: Resolution: | Keywords: performance --------------------------+-------------------------------------------------
Comment(by ehuelsmann):
When a full set of valid initargs is available, the ones actually provided only need to be MEMBER checked to be in the set.
#67: initarg checking performance --------------------------+------------------------------------------------- Reporter: ehuelsmann | Owner: somebody Type: enhancement | Status: new Priority: major | Milestone: unscheduled Component: CLOS | Version: Resolution: | Keywords: performance --------------------------+-------------------------------------------------
Comment(by ehuelsmann):
The change has been implemented for the instance creation and instance reinitialization cases in r13219 and r13220.
I'm not sure we need the other two cases at all; presumably, UPDATE- INSTANCE-FOR-REDEFINED-CLASS will be called only a limited number of times: the exact number of live instances when the class is redefined.
UPDATE-INSTANCE-FOR-DIFFERENT-CLASS will be called through CHANGE-CLASS, which can be any number of times, but is much more complex to cache, since multiple dispatch arguments are available. [the currently available infrastructure doesn't work with more than 1 specializing argument.]
The commits do leave some room for finer cache granularity.
armedbear-ticket@common-lisp.net