The Kitchen Sink and Other Oddities

Atabey Kaygun

A comparison of different map functions in lisp

Description of the problem

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.

Test code

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.