因为我是 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!这太不合理了,但我不知道为什么。我该怎么做才能进行优化?
您正在进行重复的递归调用,而没有打开足够的优化来启用尾调用消除(SBCL 会这样做,但仅当您将“优化速度”设置为高且“为调试信息优化”设置为低时)。
Common Lisp 标准将尾调用消除作为实现质量问题,并提供了其他循环结构(如 LOOP 或 DO,两者都可能适合此应用程序)。
此外,由于需要引入其运行时环境和基础映像,新启动的 SBCL 可能会比您预期的要大。