Can someone help explain the following benchmark results? This is from
CLisp under Linux:
[9]> (setf j 0)
0
[10]> (defun foo () (dotimes (i 10000) (incf j)))
FOO
[11]> (time (foo))
Real time: 0.032832 sec.
Run time: 0.03 sec.
Space: 0 Bytes
NIL
[12]> (compile 'foo)
[Warnings about undeclared J snipped]
FOO ;
2 ;
2
[13]> (time (foo))
Real time: 0.002833 sec.
Run time: 0.0 sec.
Space: 0 Bytes
NIL
[14]> (time (dotimes (i 10000) (incf j)))
Real time: 0.13893 sec.
Run time: 0.14 sec.
Space: 1801072 Bytes
GC: 3, GC time: 0.03 sec.
NIL
[15]>
Why is an interpreted function four times faster than running the same
code as a top-level form? Why does the top-level form cons so much?
E.
···@jpl.nasa.gov (Erann Gat) writes:
> Can someone help explain the following benchmark results? This is from
> CLisp under Linux:
>
> [9]> (setf j 0)
> 0
> [10]> (defun foo () (dotimes (i 10000) (incf j)))
> FOO
> [11]> (time (foo))
>
> Real time: 0.032832 sec.
> Run time: 0.03 sec.
> Space: 0 Bytes
> NIL
> [12]> (compile 'foo)
>
> [Warnings about undeclared J snipped]
> FOO ;
> 2 ;
> 2
> [13]> (time (foo))
>
> Real time: 0.002833 sec.
> Run time: 0.0 sec.
> Space: 0 Bytes
> NIL
> [14]> (time (dotimes (i 10000) (incf j)))
>
> Real time: 0.13893 sec.
> Run time: 0.14 sec.
> Space: 1801072 Bytes
> GC: 3, GC time: 0.03 sec.
> NIL
> [15]>
>
> Why is an interpreted function four times faster than running the same
> code as a top-level form? Why does the top-level form cons so much?
>
> E.
Maybe there's no GC activity until you cross a a certain
threshold, and this threshold is not reached by running the
interpreted version _once_?
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
In article <··············@raw.grenland.fast.no>, Raymond Wiker
<·············@fast.no> wrote:
> ···@jpl.nasa.gov (Erann Gat) writes:
>
> > Can someone help explain the following benchmark results? This is from
> > CLisp under Linux:
> >
> > [9]> (setf j 0)
> > 0
> > [10]> (defun foo () (dotimes (i 10000) (incf j)))
> > FOO
> > [11]> (time (foo))
> >
> > Real time: 0.032832 sec.
> > Run time: 0.03 sec.
> > Space: 0 Bytes
> > NIL
> > [12]> (compile 'foo)
> >
> > [Warnings about undeclared J snipped]
> > FOO ;
> > 2 ;
> > 2
> > [13]> (time (foo))
> >
> > Real time: 0.002833 sec.
> > Run time: 0.0 sec.
> > Space: 0 Bytes
> > NIL
> > [14]> (time (dotimes (i 10000) (incf j)))
> >
> > Real time: 0.13893 sec.
> > Run time: 0.14 sec.
> > Space: 1801072 Bytes
> > GC: 3, GC time: 0.03 sec.
> > NIL
> > [15]>
> >
> > Why is an interpreted function four times faster than running the same
> > code as a top-level form? Why does the top-level form cons so much?
> >
> > E.
>
> Maybe there's no GC activity until you cross a a certain
> threshold, and this threshold is not reached by running the
> interpreted version _once_?
That would not explain why the top-level version conses and the
interpreted function doesn't. Also, even if you take out the GC time
(0.03 sec) the top-level version is still three times slower.
E.
> * In message <····················@192.168.1.50>
> * On the subject of "Weird benchmark results"
> * Sent on Mon, 25 Feb 2002 22:37:30 -0800
> * Honorable ···@jpl.nasa.gov (Erann Gat) writes:
>
> Can someone help explain the following benchmark results? This is from
> CLisp under Linux:
>
> [9]> (setf j 0)
> 0
> [10]> (defun foo () (dotimes (i 10000) (incf j)))
> FOO
> [11]> (time (foo))
>
> Real time: 0.032832 sec.
> Run time: 0.03 sec.
> Space: 0 Bytes
> NIL
> [12]> (compile 'foo)
>
> [Warnings about undeclared J snipped]
> FOO ;
> 2 ;
> 2
now FOO is compiled, right?
> [13]> (time (foo))
>
> Real time: 0.002833 sec.
> Run time: 0.0 sec.
> Space: 0 Bytes
> NIL
> [14]> (time (dotimes (i 10000) (incf j)))
>
> Real time: 0.13893 sec.
> Run time: 0.14 sec.
> Space: 1801072 Bytes
> GC: 3, GC time: 0.03 sec.
> NIL
> [15]>
>
> Why is an interpreted function four times faster than running the same
> code as a top-level form? Why does the top-level form cons so much?
you compiled FOO, didn't you?!
incf is a macro and it is expanded every time you call it - 10000 times
- in the interpreted top-level form.
it is expanded at compile time just once, so the compiled function is
non-consing.
--
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
Lisp is a way of life. C is a way of death.
In article <··············@gnu.org>, ···@gnu.org wrote:
> > * In message <····················@192.168.1.50>
> > * On the subject of "Weird benchmark results"
> > * Sent on Mon, 25 Feb 2002 22:37:30 -0800
> > * Honorable ···@jpl.nasa.gov (Erann Gat) writes:
> >
> > Can someone help explain the following benchmark results? This is from
> > CLisp under Linux:
> >
> > [9]> (setf j 0)
> > 0
> > [10]> (defun foo () (dotimes (i 10000) (incf j)))
> > FOO
> > [11]> (time (foo))
[Note foo is not compiled here]
> >
> > Real time: 0.032832 sec.
> > Run time: 0.03 sec.
> > Space: 0 Bytes
> > NIL
> > [12]> (compile 'foo)
> >
> > [Warnings about undeclared J snipped]
> > FOO ;
> > 2 ;
> > 2
>
> now FOO is compiled, right?
Yes, but it wasn't the first time I ran it.
> > [13]> (time (foo))
> >
> > Real time: 0.002833 sec.
> > Run time: 0.0 sec.
> > Space: 0 Bytes
> > NIL
> > [14]> (time (dotimes (i 10000) (incf j)))
> >
> > Real time: 0.13893 sec.
> > Run time: 0.14 sec.
> > Space: 1801072 Bytes
> > GC: 3, GC time: 0.03 sec.
> > NIL
> > [15]>
> >
> > Why is an interpreted function four times faster than running the same
> > code as a top-level form? Why does the top-level form cons so much?
>
> you compiled FOO, didn't you?!
Only the second time I ran it. The first time it was not compiled, but it
ran in 0.03 seconds, four times faster than when the code was run at top
level. (When foo is compiled it runs in 0.002 seconds, ten times faster
than the non-compiled version, and forty times faster than the top level
form.)
E.
···@jpl.nasa.gov (Erann Gat) writes:
> Why is an interpreted function four times faster than running the same
> code as a top-level form? Why does the top-level form cons so much?
Can you inspect (symbol-function 'foo) after defun-ing it?
Maybe clisp macroexpands the body of defuns...
--
(espen)
In article <··············@merced.netfonds.no>, Espen Vestre
<·····@*do-not-spam-me*.vestre.net> wrote:
> ···@jpl.nasa.gov (Erann Gat) writes:
>
> > Why is an interpreted function four times faster than running the same
> > code as a top-level form? Why does the top-level form cons so much?
>
> Can you inspect (symbol-function 'foo) after defun-ing it?
> Maybe clisp macroexpands the body of defuns...
Nope, that doesn't seem to be the case:
[1]> (defun foo () (incf j))
FOO
[2]> (inspect #'foo)
#<CLOSURE COMMON-LISP-USER::FOO NIL
(DECLARE (SYSTEM::IN-DEFUN COMMON-LISP-USER::FOO))
(BLOCK COMMON-LISP-USER::FOO (INCF COMMON-LISP-USER::J))>: atom
type: FUNCTION
class: #1=#<BUILT-IN-CLASS FUNCTION>
INSPECT-- type :h for help; :q to return to the REPL ---> :q
[3]>
E.
···@jpl.nasa.gov (Erann Gat) writes:
> In article <··············@merced.netfonds.no>, Espen Vestre
> <·····@*do-not-spam-me*.vestre.net> wrote:
>
> > ···@jpl.nasa.gov (Erann Gat) writes:
> >
> > > Why is an interpreted function four times faster than running the same
> > > code as a top-level form? Why does the top-level form cons so much?
> >
> > Can you inspect (symbol-function 'foo) after defun-ing it?
> > Maybe clisp macroexpands the body of defuns...
>
> Nope, that doesn't seem to be the case:
>
> [1]> (defun foo () (incf j))
> FOO
> [2]> (inspect #'foo)
> #<CLOSURE COMMON-LISP-USER::FOO NIL
> (DECLARE (SYSTEM::IN-DEFUN COMMON-LISP-USER::FOO))
> (BLOCK COMMON-LISP-USER::FOO (INCF COMMON-LISP-USER::J))>: atom
> type: FUNCTION
> class: #1=#<BUILT-IN-CLASS FUNCTION>
> INSPECT-- type :h for help; :q to return to the REPL ---> :q
That's a really brain-dead way to check -- of course it's going to
give you the unexpanded version for readability. In fact, CLISP
*does* expand interpreted functions once, so I'm pretty sure that's
exactly what you were seeing.
[1]> (defmacro foo ()
(princ 'expanding) (terpri)
'(quote foo))
FOO
[2]> (defun test ()
(dotimes (i 10)
(princ (foo)) (terpri)))
EXPANDING
TEST
[3]> (test)
FOO
FOO
FOO
FOO
FOO
FOO
FOO
FOO
FOO
FOO
NIL
[4]> (dotimes (i 10)
(princ (foo)) (terpri))
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
EXPANDING
FOO
NIL
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'