haskell - Haskell 中的迭代和垃圾收集

标签 haskell garbage-collection ghc

我有一个关于 GHC 如何实现简单代码的问题。性能和技术问题。

这是 John Hughes 的“为什么函数式编程很重要”文章中的一个简单示例。平方根计算。

为了进行计算,我们需要之前的近似值,我们可以使用迭代函数来创建具有近似值的列表:

[a0, f(a0), f(f(a0), ...] 等等

然后 with inside 会在方便的时候停止:

within eps (a:b:xs) = if abs(a-b) < eps then b else within eps (b:xs)

问题是如何在恒定空间中执行此操作?

GC 是否知道在递归调用中,在 eps (b: xs) 内列表的头 a 不再处于范围内,然后将其收集?

如果是这种情况,那么在每次迭代时,GHC 是否总是创建然后销毁内存中的一个位置(变量)?在变量总是被重用的过程语言中,如何才能表现得那么好?

最佳答案

Does the GC know in the recursive call, within eps (b: xs) that head a of the list is no longer in scope and then it is collected?

正确。

If this is the case, then at each iteration, would the GHC always create and then destroy a location in memory (variable)?

对于这个例子,几乎可以肯定是的。在某些情况下,列表融合可以将基于列表的算法转变为紧密的非分配循环;如果您仅使用内置函数来生成和使用列表,则最有可能发生这种情况。

how can this perform as well as in a procedural language where the variable is always reused?

分配器和 GC 已针对进行大量分配和收集进行了调整。通常分配只是碰撞一个指针。有时你会遇到 GC,但只需要从第一代复制一个 Float 到第二代(或者只需要一个 Float 和一些闭包或其他什么 - 你会得到这个想法,大部分数据不需要被触及,因为它是不可访问的),这同样非常便宜。显然,存在一些开销,但通常您所做的计算足够复杂,以至于需要花费大部分运行时间。

关于haskell - Haskell 中的迭代和垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66535405/

相关文章:

haskell - Haskell 学习者关于过滤和折叠的小问题

list - unzip的概括是什么?

java - 找出垃圾收集器正在释放哪些对象:

java - Java中垃圾回收的合格变量

Java 1.8 安全点超时

haskell - 参数类型的 GHC 性能影响

Haskell:安装 hsc2hs

haskell - Haskell 和 Idris : Reflection of Runtime/Compiletime in the type universes 之间的区别

performance - 为什么 `(map digitToInt) . show` 这么快?

haskell - 使用 GHC API 进行 "dry run"的代码编译