Mai*_*ein 2 garbage-collection haskell
然后是编码:使用未装箱的类型(无GC),最小化惰性结构分配.以包装形式保存长寿数据.测试和基准.
1.)什么是未装箱的类型?我很确定他正在谈论数据类型,例如Just x或IO y(盒装).但是newtypes怎么样?如果我理解正确,newtype根本没有开销,因此不应该算作盒装类型?
2.)他的意思是Keep long lived data around in packed form.什么?
3.)我还能做些什么来防止GC暂停?
1.未装箱的类型是Haskell中的原语.例如,Int定义为:( data Int = GHC.Types.I# GHC.Prim.Int#对于GHC编译器).尾随#符号用于表示基元(这只是约定).Haskell中并不存在原始数据.您无法定义其他基元.当它们出现在代码中时,编译器负责将它们转换为"真正的"函数调用(函数也可以是原语)和数据类型.
是的,newtype不会另外"装箱"类型.但是你不能拥有一个包含基元的newtype - newtype Int2 = Int2 Int#虽然data Int2 = Int2 Int#很好但是无效.
在您链接的问题的上下文中,原始类型和盒装类型之间的主要区别在于它们在内存中的表示方式.原始类型意味着没有指针可供遵循.指向Int# 必须指向数字值的指针,而指向a的指针Int可能指向指向thunk的thunk ......等等.请注意,这意味着基元始终是严格的.如果您认为这将是一个问题,请使用UNPACKpragma,它将删除任何"中间"装箱.那是,
data D = D (Int, Int)
Run Code Online (Sandbox Code Playgroud)
被指针(D)存储为指针(元组)到包含两个指针(Ints)的存储器块,每个指针指向一个实际的指针Int#.然而,
data D = D {-# UNPACK #-} !(Int, Int)
Run Code Online (Sandbox Code Playgroud)
被存储为指针(D)到两个Ints,从而移除一级拳击.请注意!.这表明该字段是严格的并且是必需的UNPACK.
2.任何将使用多态函数调用的数据都应该保持打包状态,因为传递给多态函数的解包数据将被重新打包(引入不必要的开销).保持长期数据打包的原因在于它更可能用于需要重新打包的中间数据类型或函数,而使用短期数据更容易控制,这些数据仅在传递给少数函数之前传递给垃圾收集.
3.在99%的情况下,您不会遇到垃圾收集器暂停的问题.通常,您无法保证GC不会暂停.我唯一的建议是,不要试图重新发明轮子.有一些库设计用于具有大量数据(修复,矢量等)的高性能计算.如果你试图自己实现它,很可能,它们做得更好!
| 归档时间: |
|
| 查看次数: |
609 次 |
| 最近记录: |