[lisp]деструктивность и выделение памяти
От: Аноним  
Дата: 18.04.08 19:25
Оценка:
Есть 2 функции, первая без сайд-эффектов генерирует новый список, вторая — деструктивно меняет значение одного из своих аргументов:
(defun f (a)
    (mapcar #'1+ a))

(defun f2 (a b)
    (map-into b #'1+ a))

Вторая функция, насколько я понимаю, должна быть и быстрей и меньше использовать память, за счет того, не происходит дополнительного выделения памяти при каждом вызове.
Но тестовые запуски показывают обратное — мало того, что f2 работает почти на 2 порядка медленней, так еще и памяти. как будто, больше потребляет:
CL-USER> (let ((xs (make-list 1000 :initial-element 0)))
       (time
        (dotimes (i 100)
          (reduce #'+ (f xs)))))
Evaluation took:
  0.01 seconds of real time
  0.008999 seconds of user run time
  0.0 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  2,399,464 bytes consed.
NIL
CL-USER> (let ((xs (make-list 1000 :initial-element 0)))
       (let ((ys (make-list 1000)))
         (time
          (dotimes (i 100)
               (reduce #'+ (f2 xs ys))))))
Evaluation took:
  0.647 seconds of real time
  0.646902 seconds of user run time
  0.0 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  3,202,280 bytes consed.

При использовании вектора вместо списка разница в скорости уменьшается до 2 раз: с использованием f — 0.012, с f2 — 0.022.

И я не могу понять, чем объясняется большая скорость функции f? И прав ли я, что функция f по логике должна больше выделять памяти?
И может быть, кого-нибудь не затруднит попробовать такой тест на haskell'е?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.