Path: utzoo!censor!geac!torsqnt!lethe!yunexus!ists!helios.physics.utoronto.ca!news-server.csri.toronto.edu!bonnie.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!think.com!linus!linus!babypuss!djb From: djb@babypuss.mitre.org (David J. Braunegg) Newsgroups: comp.lang.lisp Subject: AKCL funcall speedup Message-ID: <127670@linus.mitre.org> Date: 10 Jan 91 14:13:30 GMT Sender: usenet@linus.mitre.org Organization: The MITRE Corporation Lines: 130 Nntp-Posting-Host: babypuss.mitre.org 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)) 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) do-cost real time : 0.700 secs run time : 0.683 secs regular-call-cost real time : 2.717 secs run time : 2.717 secs funcall-cost real time : 3.833 secs run time : 3.800 secs regular-call-cost-fixnum real time : 2.633 secs run time : 2.650 secs funcall-cost-fixnum 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 NIL