评论由:adrianm 发布
appendo 和 membero 特别慢。
(dotimes (link: i ie5) (run* (link: q) (== q true))) 约需 ~4500ms,大约比 JVM 慢 10 倍。
在分析后,我发现了问题——非常标准的递归优化是必要的,它在执行代码时会递归地重新访问(通过重新统一)lvars。例如:
对于 appendo,(run 5 (link: q) (fresh (link: x y) (appendo x y q))) 将展开成类似的东西...
((_0) (_0 . _1) (_0 _1 . _2) ... ))
这很慢,因为每个新列表实际上都要重新访问之前统一的每个 lvar。
周末我会花更多的时间来调查这个问题,但我想这可能会简单地通过默认不生成唯一的 lvars 来解决,因为这样 identical? 的统一检查就可以捕捉到任何尝试的访问。