
(defclass base-class ()
  ((slot-one :initform (random 1.0f0) :type single-float
	     :accessor class-slot-one)
   (slot-two :initform (random 1.0f0) :type single-float
	     :accessor class-slot-two)))

(defclass sub-class (base-class)
  ((slot-three :initform (random 1.0f0) :type single-float
	       :accessor class-slot-three)
   (slot-four  :initform (random 1.0f0) :type single-float
	       :accessor class-slot-four)))

(defgeneric swizzle-g (instance datum))

(defmethod swizzle-g ((instance base-class) datum)
  (declare (type single-float datum)
	   (optimize (speed 3) (safety 0)))
  (setf (class-slot-two instance) datum)
    (<= 0.0f0
	(the single-float (* (the single-float (class-slot-one instance))
			     (the single-float (class-slot-two instance))))))

(defmethod swizzle-g ((instance sub-class) datum)
  (declare (type single-float datum)
	   (optimize (speed 3) (safety 0)))
  (setf (class-slot-two instance) datum)
  (<= 0.0f0
      (the single-float
	(+
	 (the single-float (* (the single-float (class-slot-one instance))
			      (the single-float (class-slot-two instance))))
	 (the single-float (* (the single-float (class-slot-three instance))
			      (the single-float (class-slot-four instance))))))))

(let ((base (make-instance 'base-class))
      (sub  (make-instance 'sub-class))
      (v1   (the single-float (random 1.0f0)))
      (v2   (the single-float (random 1.0f0)))
      (v3   (the single-float (random 1.0f0)))
      (v4   (the single-float (random 1.0f0))))
  (declare (type single-float v1 v2 v3 v4))
  (time (loop for jj fixnum below 10000000
	   do (progn
		(swizzle-g base v1)
		(swizzle-g sub  v2)
		(swizzle-g sub  v3)
		(swizzle-g base v4)))))

(defun swizzle-gb (instance datum)
  (declare (type single-float datum)
	   (optimize (speed 3) (safety 0)))
  (setf (slot-value instance 'slot-two) datum)
    (<= 0.0f0
	(the single-float (* (the single-float (slot-value instance
							   'slot-one))
			     (the single-float (slot-value instance
							   'slot-two))))))

(defun swizzle-gs (instance datum)
  (declare (type single-float datum)
	   (optimize (speed 3) (safety 0)))
  (setf (slot-value instance 'slot-two) datum)
  (<= 0.0f0
      (the single-float
	(+
	 (the single-float (* (the single-float (slot-value instance
							    'slot-one))
			      (the single-float (slot-value instance
							    'slot-two))))
	 (the single-float (* (the single-float (slot-value instance
							    'slot-three))
			      (the single-float (slot-value instance
							    'slot-four))))))))

(let ((base (make-instance 'base-class))
      (sub  (make-instance 'sub-class))
      (v1   (the single-float (random 1.0f0)))
      (v2   (the single-float (random 1.0f0)))
      (v3   (the single-float (random 1.0f0)))
      (v4   (the single-float (random 1.0f0))))
  (declare (type single-float v1 v2 v3 v4))
  (time (loop for jj fixnum below 10000000
	   do (progn
		(swizzle-gb base v1)
		(swizzle-gs sub  v2)
		(swizzle-gs sub  v3)
		(swizzle-gb base v4)))))

(defstruct (base-struct)
  (slot-one (random 1.0f0) :type single-float)
  (slot-two (random 1.0f0) :type single-float))

(defstruct (sub-struct (:include base-struct))
  (slot-three (random 1.0f0) :type single-float)
  (slot-four (random 1.0f0) :type single-float))

(defun swizzle-b (instance datum)
  (declare (type single-float datum)
	   (optimize (speed 3) (safety 0)))
  (setf (base-struct-slot-two instance) datum)
  (<= 0.0f0
      (the single-float (* (the single-float (base-struct-slot-one
					         instance))
			   (the single-float (base-struct-slot-two
					         instance))))))

(defun swizzle-s (instance datum)
  (declare (type single-float datum)
	   (optimize (speed 3) (safety 0)))
  (setf (sub-struct-slot-two instance) datum)
  (<= 0.0f0
      (the single-float
	(+
	 (the single-float (* (the single-float (sub-struct-slot-one
						 instance))
			      (the single-float (sub-struct-slot-two
						 instance))))
	 (the single-float (* (the single-float (sub-struct-slot-three
						 instance))
			      (the single-float (sub-struct-slot-four
						 instance))))))))

(let ((base (make-base-struct))
      (sub  (make-sub-struct))
      (v1   (the single-float (random 1.0f0)))
      (v2   (the single-float (random 1.0f0)))
      (v3   (the single-float (random 1.0f0)))
      (v4   (the single-float (random 1.0f0))))
  (declare (type single-float v1 v2 v3 v4))
  (time (loop for jj fixnum below 10000000
	   do (progn
		(swizzle-b base v1)
		(swizzle-s sub  v2)
		(swizzle-s sub  v3)
		(swizzle-b base v4)))))

