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

funcall speedup

I was looking through the kcl mail archive and ran across a message
from Bob Boyer (boyer@rascal.ics.utexas.edu) dated 18 Oct 89 concering
the speedups to funcall in AKCL.  The gist of the message was that
funcall was fast if the function is declared appropriately, especially
if it returns a single value.  Test code was given, which I give
below.  I also tried it with the function declared with fixnums
(foo-fixnum) and with no declarations (foo-none).

Strangely enough, the time for the funcall to foo-fixnum takes longer
than the call to foo-none.  Can anyone explain what is going wrong?

(in-package 'user)

;;; original test code

(proclaim '(function foo (t) t))

(defun foo (x) x)

(defun do-cost (n)
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      nil))  ; Do nothing.
(defun regular-call-cost (n)
  (declare (fixnum n))
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      (foo t)))  ;  Call foo in the ordinary way.

(defun funcall-cost (n fn)
  (declare (fixnum n))
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      (funcall fn t)))   ;  The value of the funcall is ignored. 

;;; fixnum declaration

(proclaim '(function foo-fixnum (fixnum) fixnum))

(defun foo-fixnum (x)
  (declare (fixnum x))
;;; Use arg of 1 for the fixnum calls
(defun regular-call-cost-fixnum (n)
  (declare (fixnum n))
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      (foo-fixnum 1)))  ;  Call foo-fixnum in the ordinary way.

(defun funcall-cost-fixnum (n fn)
  (declare (fixnum n))
  (do ((i n (1- i))) ((= i 0))
      (declare (fixnum i))
      (funcall fn 1)))   ;  The value of the funcall is ignored. 

;;; no declarations

(defun foo-none (x) x)

;;; test code

(defun report (n)
  (format t "do-cost")
  (time (do-cost n))
  (format t "~%regular-call-cost")
  (time (regular-call-cost n))
  (format t "funcall-cost")
  (time (funcall-cost n #'foo))
  ;; fixnum declaration
  (format t "~%regular-call-cost-fixnum")
  (time (regular-call-cost-fixnum n))
  (format t "funcall-cost-fixnum")
  (time (funcall-cost-fixnum n #'foo-fixnum))
  ;; no declaration, arg t
  (format t "~%regular-call-cost-none, arg t")
  (time (regular-call-cost n))
  (format t "funcall-cost-none, arg t")
  (time (funcall-cost n #'foo-none))
  ;; no declaration, arg 1
  (format t "~%regular-call-cost-none, arg 1")
  (time (regular-call-cost-fixnum n))
  (format t "funcall-cost-none, arg 1")
  (time (funcall-cost-fixnum n #'foo-none)))

Here we see that the funcalls to the function with no declarations is
faster than the funcalls to the function with fixnum declarations.

>(report 1000000)
real time : 0.700 secs
run time  : 0.683 secs

real time : 2.717 secs
run time  : 2.717 secs
real time : 3.833 secs
run time  : 3.800 secs

real time : 2.633 secs
run time  : 2.650 secs
real time : 74.383 secs
run time  : 71.650 secs

regular-call-cost-none, arg t
real time : 2.800 secs
run time  : 2.583 secs
funcall-cost-none, arg t
real time : 23.917 secs
run time  : 22.450 secs

regular-call-cost-none, arg 1
real time : 2.667 secs
run time  : 2.517 secs
funcall-cost-none, arg 1
real time : 24.217 secs
run time  : 22.583 secs