GHC 是否支持 GC-less 编程?
Does GHC support GC-less programming?
使用 -S
选项和一个简单的程序:
main = do
print "Hello"
main
我看到它产生了一些垃圾:
[...]
1024232 4904 45992 0.000 0.000 0.428 0.530 0 0 (Gen: 1)
0 0.000 0.000
1,242,080,056 bytes allocated in the heap
271,656 bytes copied during GC
[...]
但在删除 print
之后显然没有。是否有可用于编写无 GC 程序的核心库的无分配子集?
编辑:最近还有一项关于线性类型的工作似乎有可能启用此类功能。
您偶尔可以生成执行很少甚至不执行垃圾收集的小程序。例如下面的程序:
main = print $ sum [(1::Int)..1000000000]
如果使用 -O2
编译,应该 运行 无需分配太多或执行任何值得一提的 GC。
但是,这通常仅限于可以编译成具有 "unboxed" 数据类型(在这种情况下,未装箱的 Int#
值)而没有代数数据结构(在这种情况下,该列表已融合不存在)。有一组有限的更复杂的数据结构(例如,未装箱的 Vector
s)也可以在没有分配的情况下进行操作,如果你非常小心,你可能能够编写在不分配的情况下对此类结构进行操作的算法很多。
例如下面的程序:
import Control.Monad
import qualified Data.Vector.Unboxed.Mutable as V
main :: IO ()
main = do
v <- V.new 1000000
forM_ [0..999999] $ \i -> do
V.write v i i
replicateM_ 999 $
forM_ [0..499999] $ \i -> do
V.swap v i (999999 - i)
print =<< V.read v 123
分配一个百万整数数组,然后运行通过它 999 次反转所有元素。
使用 GHC 版本 8.4.3 和 -O2
编译,它在开始时分配了大约 8 个演出,但在 运行 列表反转时不进行任何额外分配。我的猜测是您可以实现一些有用的东西,例如就地快速排序,使用类似的技术而不进行任何分配,从而跳过任何 GC。
不过,作为一般规则,分配实际上是 GHC Haskell 代码编译方式的基本组成部分 运行,因此没有合理的库子集或编程技术可以保证 GC-free 编程。
使用 -S
选项和一个简单的程序:
main = do
print "Hello"
main
我看到它产生了一些垃圾:
[...]
1024232 4904 45992 0.000 0.000 0.428 0.530 0 0 (Gen: 1)
0 0.000 0.000
1,242,080,056 bytes allocated in the heap
271,656 bytes copied during GC
[...]
但在删除 print
之后显然没有。是否有可用于编写无 GC 程序的核心库的无分配子集?
编辑:最近还有一项关于线性类型的工作似乎有可能启用此类功能。
您偶尔可以生成执行很少甚至不执行垃圾收集的小程序。例如下面的程序:
main = print $ sum [(1::Int)..1000000000]
如果使用 -O2
编译,应该 运行 无需分配太多或执行任何值得一提的 GC。
但是,这通常仅限于可以编译成具有 "unboxed" 数据类型(在这种情况下,未装箱的 Int#
值)而没有代数数据结构(在这种情况下,该列表已融合不存在)。有一组有限的更复杂的数据结构(例如,未装箱的 Vector
s)也可以在没有分配的情况下进行操作,如果你非常小心,你可能能够编写在不分配的情况下对此类结构进行操作的算法很多。
例如下面的程序:
import Control.Monad
import qualified Data.Vector.Unboxed.Mutable as V
main :: IO ()
main = do
v <- V.new 1000000
forM_ [0..999999] $ \i -> do
V.write v i i
replicateM_ 999 $
forM_ [0..499999] $ \i -> do
V.swap v i (999999 - i)
print =<< V.read v 123
分配一个百万整数数组,然后运行通过它 999 次反转所有元素。
使用 GHC 版本 8.4.3 和 -O2
编译,它在开始时分配了大约 8 个演出,但在 运行 列表反转时不进行任何额外分配。我的猜测是您可以实现一些有用的东西,例如就地快速排序,使用类似的技术而不进行任何分配,从而跳过任何 GC。
不过,作为一般规则,分配实际上是 GHC Haskell 代码编译方式的基本组成部分 运行,因此没有合理的库子集或编程技术可以保证 GC-free 编程。