1
4
代码中的一个错误是使用eq.eq比较身份。 eq不用于比较数字。两个数的eq可以是真的,也可以是假的。 如果要按标识、值或字符比较,请使用eql。不是等式 事实上
只是
对于您的代码,eq错误 可以 意味着在递归调用中调用permute,而实际上没有从列表中删除数字。 除此之外,我认为SBCL只是忙于内存管理。我的Mac上的sbcl获得了大量的内存(超过一GB),正忙着做一些事情。一段时间后,计算出结果。 递归函数生成大量的“垃圾”。lispworks说:1360951922字节 也许你能想出一个更有效的实现方法? 更新: 垃圾 Lisp提供了一些自动的内存管理,但这并不能使程序员不去考虑空间效应。 Lisp同时使用堆栈和堆来分配内存。堆可能以特定的方式为GC构建——例如在代、半空间和/或区域中。有精确的垃圾收集器和“保守”的垃圾收集器(由Intel机器上的sbcl使用)。 当程序运行时,我们可以看到各种效果:
不过,还有更多的问题。但是对于上面的每一个,Lisp程序员(以及使用垃圾收集的语言实现的每一个其他程序员)都必须学习如何处理这个问题。
上面讨论的是真实程序的空间问题。理想情况下,我们的编译器或运行时基础结构可以提供一些自动支持来处理这些问题。但事实上,这并不真正奏效。大多数Lisp系统都提供了处理这一问题的低级功能,而Lisp提供了可变对象——因为现实世界的Lisp程序的经验表明,程序员确实希望使用它们来优化程序。如果您有一个大型的CAD应用程序来计算涡轮叶片的形状,那么关于不可变内存的理论/纯粹的观点就不适用了——开发人员想要更快/更小的代码和更小的运行时占用空间。 |
2
2
在大多数平台上,sbcl都使用一代垃圾收集器,这意味着对于收集而言,存活超过一定数量的已分配内存将很少被考虑。对于给定的测试用例,您的算法生成了太多的垃圾,以至于它多次触发GC,以至于实际的结果(显然必须在整个函数运行时生存下来)被保存,也就是说,移动到最后一代,而这一代的收集要么非常少,要么根本不收集。因此,第二次运行将在32位系统的标准设置上耗尽堆(512 MB,可以通过运行时选项增加)。
通过使用
|
3
1
从输出的角度看,你看到的是黏液回复,对吗? 尝试更改为“*劣质lisp*”缓冲区,您可能会看到sbcl已下降到ldb(内置的低级调试器)。最有可能的是,您已经成功地打开了调用堆栈。 |
kaligne · 编辑文件时幻灯片自动完成 9 年前 |