Since I spirit people away from python and javascript, I thought I better
have a look at whatever python is like now (I looked at it last around
2.7->3.0). Here is my attempt at a pythonic recursive factorial benchmark.
```
def fact(x,f):
if x==0:
return(f);
else:
return(fact(x-1,x*f));
##The following single line seems to be part of function definition:
pass; ## No longer in the function definition
import timeit;
timeit.timeit(stmt=lambda:fact(x=993,f=1),number=10000);
```
>29.585241416003555
Seconds, I imagine. Boy is that precise. With timeit, x>993 or without
timeit, x>997 gave me
```
RecursionError: maximum recursion depth exceeded in comparison
```
and number=10000 let me run the benchmark in about 30 seconds.
What about lisp? Disappointingly, ECL misses the tail recursion and stack
depth tops out at x being 8879. ECL uses two kinds of compilation. 'compile
does on-the-fly byte-compilation whereas 'compile-file rolls through $CC.
The standard is a little nuanced on the topic.
```
(defun fact (x f) (if (zerop x) f (fact (1- x) (* x f))))
(time (dotimes (count 10000) (fact 993 1)))
```
real time : 23.190 secs
run time : 27.590 secs
gc count : 2500 times
consed : 7437927024 bytes
NIL
```
..Kind of slow!
Let's jump into sbcl for a second:
```
* (defun fact (x f) (if (zerop x) f (fact (1- x) (* x f))))
* (time (dotimes (count 10000) (fact 993 1)))
Evaluation took:
2.545 seconds of real time
2.540000 seconds of total run time (2.440000 user, 0.100000 system)
[ Run times consist of 0.276 seconds GC time, and 2.264 seconds non-GC time. ]
99.80% CPU
5,079,065,766 processor cycles
5,923,816,112 bytes consed
NIL
```
Annoyingly, while the standard constrains what the 'time macro reports, it
does not specify what the output will look like as you can see. Let's try
ecl again. after running it through the default 'compile-file.
```ecl1.lisp
(defun fact (x f) (if (zerop x) f (fact (1- x) (* x f))))
(time (dotimes (count 10000) (fact 993 1)))
(si:quit)
```
```ecl
> (compile-file "ecl1.lisp" :load t)
real time : 10.029 secs
run time : 14.120 secs
gc count : 2359 times
consed : 6801762144 bytes
```
A little better! Still more than four times worse than sbcl. We can tell
that the lisp compilers aren't cheating in the benchmark because the number
of bytes consed (~allocated) looks consistent.
POST SCRIPTUM
I was going to bang on a lot here, but I guess that can be another phlog.
If anyone wants to show me another python factorial definition/benchmark,
please point me to your phlog (whether or no you're a pro).
Lisp or another language either for that matter.