#4 make-instance

ちゃんと profile とかしてないんだが、どうも generic-function の呼び出しがネックな気がする。

(make-instance 'foo :key <value>)

;;; 0
(defmethod make-instance ((class symbol) &rest initargs)
  (apply #'make-instance (find-class class) initargs)) ; 1へ

;;; 1
(defmethod make-instance ((class standard-class) &rest initargs)
  (let ((instance (allocate-instance class))) ; 2へ
    (apply #'initialize-instance instance initargs) ;3から4へ
    instance))

;;; 2
(defmethod allocate-instance ((class standard-class))
  (std-allocate-instance class))

;;; 3
(defmethod initialize-instance ((instance standard-object) &rest initargs)
  (apply #'shared-initialize instance t initargs))

;;; 4
(defmethod shared-initialize
      ((instance standard-object) slot-name &rest all-keys)
  (dolist (slot (class-slots (class-of instance)))
    ...))

とあちこちパス回しされてたので

(defmethod make-instance ((class standard-class) &rest initargs)
  (let ((instance (std-allocate-instance class)))
    (apply #'shared-initialize instance t initargs)
    instance))

とスルーパスにしたら 10% くらい速くなった。

余談:
closette.l の file-write-time を監視して update されたらベンチする関数を timer で動かしっぱなし。

(let ((last-update (file-write-time *closette-file*))
      (buff (get-buffer-create "*Results*")))
  (defun bench ()
    (let ((update (file-write-time *closette-file*)))
      (when (> update last-update)
        (setq last-update update)
        (load-file *closette-file*)
        (closette::bootstrap)
        (defclass foo ()
          ((data :accessor foo-data  :initarg :data)))
        (message "benchmarking...")
        (let ((result (time
                       (let ((list nil))
                         (dotimes (n 500)
                           (push (make-instance 'foo :data (random 1000))
                                 list))
                         (sort list #'< :key #'foo-data)))))
          (message "benchmarking...done in ~S sec." result)
          (format (make-buffer-stream buff) "~A: ~S sec~%"
                  (format-date-string *w3c-dtf* update)
                  result)
          (refresh-screen))))))

これが4秒くらいかかってる。structure だと0.03秒くらい。