【问题标题】:Memory footprint of existentially quantified types and related optimization techniques存在量化类型的内存占用和相关优化技术
【发布时间】:2013-12-11 13:42:23
【问题描述】:

考虑以下利用存在的数据模型:

data Node a = Node a (Map TypeRep AnyNode)
data AnyNode = forall a. Show a => AnyNode a

标准类型have been explained previously的内存占用规则。现在,存在类型的规则是什么,比如AnyNode

是否有任何优化技术,例如使用unsafeCoerce 的一些变通方法可以逃避存在声明?我问这个是因为类似于Node 的类型将被放置在一个高度内存密集型库的成本中心,所以内存占用就是全部,这就是为什么最肮脏的黑客受到欢迎的原因。

【问题讨论】:

  • 我认为您已经考虑过旧的“如果您只需要Show,那么为什么不首先存储show x?”
  • @leftaroundabout 以上只是一个例子。我的实际案例涉及可变数据结构。

标签: haskell memory optimization


【解决方案1】:

ghc-datasize 包在这里可能会有所帮助:

{-# LANGUAGE RankNTypes, GADTs #-}

import GHC.DataSize

data Node = forall a. Show a => Node a 

main = do
    s <- closureSize $ Node 0 
    print s -- 24 bytes on my 64-bit system

因此,与普通的一元数据构造函数相比,Node 似乎多了一个单词,大概是因为Show 类字典指针。另外,我尝试在Node 中添加更多类约束,它们中的每一个都占用了一个额外的空间。

我不确定是否可以在特定情况下魔术掉字典指针。如果您想保留存在类型,我认为这是不可能的。

【讨论】:

  • 这是一个非常有用的工具!只是在 GHCi 中玩了几分钟就让我对某些方面大开眼界。例如,单个 TypeRep 重 408 字节 - OMG,不,谢谢,我将使用自定义字典!然而,这并不能完全回答我的问题,所以我会保持打开状态。非常感谢!
  • @NikitaVolkov 你确定TypeReps 不是共享的(即每个程序和类型只有一个)?
  • @tibbe According to docs on recursiveSize内存中的实际大小是计算出来的,所以共享值只计算一次。调用 recursiveSize [typeOf 'a', typeOf 'b'] 会得到 520recursiveSize [typeOf 'a'] - 272。所以看起来不,不幸的是,它们没有共享。
  • @NikitaVolkov:您可能还想在编译模式下乱搞,可能需要优化,因为与 GHCi 相比,大小有时会发生变化。
  • @NikitaVolkov 这听起来不对。您可以针对 GHC 提交错误吗?
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多