Почему Common Lisp (SBCL) использует так много памяти для простой программы? - PullRequest
4 голосов
/ 25 января 2012

, так как я новичок в Common Lisp, я пытался решить проблемы на SPOJ с помощью Common Lisp ( SBCL ). Первая проблема - это простая задача чтения чисел, пока не будет найдено число 42. Вот мое решение:

(defun study-num ()
  (let ((num (parse-integer (read-line t))))
    (when (not (= num 42))
      (format t "~A~%" num)
      (study-num))))
(study-num)

Решение принято. Но когда я изучил детали результата, я обнаружил, что он использует 57M MEM! Это чертовски неразумно, но я не могу понять, почему. Что я могу сделать для оптимизации?

Ответы [ 3 ]

4 голосов
/ 10 февраля 2014

Я думаю, вы не понимаете, что Common Lisp - это онлайновая языковая среда с полной библиотекой и компилятором, загруженным в ОЗУ только для того, чтобы дать вам первое приглашение. После этого загрузка вашей программы, вероятно, едва заметное увеличение размера. Lisp не компилирует и не связывает независимый исполняемый файл, состоящий только из вашего кода и любых подпрограмм lib, доступных из вашего кода. Это то, что делают C и подобные языки. Вместо этого Lisp добавляет ваш код в уже существующую онлайн-среду. Как новый пользователь это выглядит ужасно. Но если у вас есть современный компьютер общего назначения с 100 МБ ОЗУ, он быстро станет тем, о чем вы можете забыть, пользуясь преимуществами онлайн-среды. Thins также называют «динамической языковой средой».

4 голосов
/ 22 января 2015

Различные реализации Lisp имеют разные способы создания программ. Один из них - сбросить образ памяти системы Lisp и записать его на диск. При перезапуске это изображение загружается во время выполнения, а затем запускается снова. Это довольно часто.

Это также то, что делает SBCL, когда сохраняет исполняемый файл. Таким образом, этот исполняемый файл включает в себя полный SBCL.

Некоторые другие реализации создают меньшие исполняемые файлы с использованием изображений (CLISP), некоторые могут удалять неиспользуемый код из исполняемых файлов (Allegro CL, LispWorks), а другие создают очень маленькие программы путем компиляции в C (mocl).

SBCL имеет только один простой способ уменьшить размер исполняемого файла: можно сжать образ.

4 голосов
/ 25 января 2012

Вы совершаете повторяющиеся рекурсивные вызовы, при этом не включена достаточная оптимизация, чтобы включить устранение хвостовых вызовов (SBCL делает это, но только когда вы установили высокий уровень "оптимизация по скорости" и низкий уровень "оптимизация по информации отладки").

Стандарт Common Lisp оставляет устранение хвостовых вызовов в качестве проблемы качества реализации и предоставляет другие циклические конструкции (такие как LOOP или DO, обе возможно подходящие для этого приложения).

Кроме того, недавноЗапущенный SBCL, вероятно, будет больше, чем вы ожидаете, из-за необходимости использовать его среду выполнения и базовый образ.

...