When I write lisp code, I have different map functions I can use
provided by common lisp, or any other lisps. There is the familiar
mapcar
and there is the map
function. The
former takes a list and returns a list. Simple. The latter provides some
flexibility in terms of the input and output types. Today I will compare
the different versions of these map functions for two lisp interpreters:
ecl and sbcl.
The test code I am going to use is as follows
(setq VLA (make-array 9999999))
(setq VLL (make-list 9999999))
(time (progn (map 'list (lambda (x) (random 10)) VLA) nil))
(time (progn (map 'vector (lambda (x) (random 10)) VLA) nil))
(time (progn (map 'list (lambda (x) (random 10)) VLL) nil))
(time (progn (map 'vector (lambda (x) (random 10)) VLL) nil))
(time (progn (mapcar (lambda (x) (random 10)) VLL) nil))
And the results are
ECL | SBCL | |
---|---|---|
map array to list |
3.9190 [0.0012] | 0.9866 [0.0000] |
map array to array |
3.3938 [0.0030] | 0.5529 [0.0000] |
map list to list |
3.5696 [0.0063] | 0.6416 [0.0000] |
map list to array |
4.0166 [0.0033] | 1.4948 [0.0063] |
mapcar |
3.3802 [0.0010] | 1.3909 [0.0004] |
I ran the code 10 times for each interpreter and then I took the
averages. The numbers in brackets are the standard deviations. It seems
that sbcl
executes map
from array to array
very efficiently while for ecl
executes the same code on
par with mapcar
. Call me impatient: sbcl
is
very big and takes too long to launch while ecl
is very
small and fires up much faster in comparison. But it is clear that
there is no free lunch. I would pay for my initial impatience
in terms of total run time.