为什么 Common Lisp (SBCL) 会为一个简单的程序使用这么多内存?

las*_*and 4 sbcl common-lisp

因为我是 Common Lisp 的新手,所以我尝试使用 Common Lisp ( SBCL )解决SPOJ 上的问题。第一个问题是读取数字直到找到数字 42 的简单任务。这是我的解决方案:

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

解决方案被接受。但是当我查看结果的详细信息时,我发现它使用了 57M 的 MEM!这太不合理了,但我不知道为什么。我该怎么做才能进行优化?

Vat*_*ine 5

您正在进行重复的递归调用,而没有打开足够的优化来启用尾调用消除(SBCL 会这样做,但仅当您将“优化速度”设置为高且“为调试信息优化”设置为低时)。

Common Lisp 标准将尾调用消除作为实现质量问题,并提供了其他循环结构(如 LOOP 或 DO,两者都可能适合此应用程序)。

此外,由于需要引入其运行时环境和基础映像,新启动的 SBCL 可能会比您预期的要大。

  • clisp 和 SBCL 处理“代码”的方式非常不同。在 clisp 中,事物(大部分)由字节码机器进行字节编译和解释。在 SBCL 中,事物(大部分)被编译为本机代码,启动过程包括在映像中映射到初始 lisp 环境。 (3认同)