弗雷格的评估是否有系统的上限?

时间:2013-09-30 03:16:33

标签: frege

出于好奇,我在弗雷格尝试了这段代码:

println (mydrop 30000000 [1..30000001])

毋庸置疑,一个3000万条目的序列有点愚蠢,我对OOME也没问题。我想看看懒惰评估是否会在这里产生影响。结果是我的所有8个核心都以100%耗尽并留在那里直到我硬杀了这个过程。

我是否达到了系统上限?


我应该提到我使用了真实世界Haskell练习中的mydrop:

mydrop n xs = if n <= 0 || null xs
              then xs
              else mydrop (n-1) (tail xs)

2 个答案:

答案 0 :(得分:2)

现在正在追踪这个问题,但事实证明,由于JVM中缺少适当的尾调用,所有情况都无法避免。请参阅此处获取解释:https://github.com/Frege/frege/issues/65

有趣的是,下面的“等效”groovy程序(我的第一个!)表现出一种有趣的行为:

println (new IntRange(0,30_000_000).drop(29).take(3))

这需要比

更长的时间
println (new IntRange(0,30_000_000).drop(29_999_990).take(3))

Frege程序始终需要n+m个步骤,其中n是已删除项目的数量,m是所采用项目的数量,因此第一个几乎是立即的,但第二个需要2到3个。在继续drop之前,grOH计划似乎实际上意识到take之后仍然存在的列表。因此第一个版本较慢。

答案 1 :(得分:1)

我没有意识到上限。 REPL中的一个简短测试(try.frege-lang.org)显示我可以进入

drop 16_000_000 [1..16_000_000]

仅在几秒钟后完成。由于这个程序是O(n)我估计30万的最大执行时间可能是30秒,但是在32_000_000之后我会在几秒钟之后得到“服务不可用”,这通常暗示了免费Web服务的一些限制的用尽

此外,无论数量多少,上述程序的内存使用量应保持不变。如果没有,我会认为它是一个错误。

---编辑---

在2核心的2.9GHz办公电脑上试用它:像魅力一样,需要5.7秒。 6400万人需要10.5s