【问题标题】:How much extra memory take a value encoded in a algebraic type in F#?在 F# 中以代数类型编码的值需要多少额外的内存?
【发布时间】:2016-04-11 08:42:08
【问题描述】:

我正在为一种小语言做一个解释器来做数组/关系编程,就像在 kdb+ 中一样。

我想知道当像这样在 AGDT 中编码一个值时 F# 会增加多少内存:

type value =
  | Dec of int
  | Num of int array
  | Float of float array
  | Array of value
  | Arr of value array

let print x =
    printfn "%A" x


let a = [|1; 2|]
let b = Num(a)
let c = [| Dec(1); Dec(2) |]
//print (sizeof Arr) Don't have a easy way to do this

我想知道在 F# 中 a,b,c 是否具有同等性能。这个想法是解释器需要主要处理数组。

因为看起来(根据我在 SO 中的搜索).NET 没有直接的方法来检查值的内存大小,所以我在 swift 中做了类似的事情:

indirect enum ExprC {
    case IntC(x:Int32)
    case IntA(x:Array<Int32>)
    case ArrayC(x:Array<ExprC>)
}
let values:[Int32] = [1, 2]
let v1 = ExprC.ArrayC(x: [ExprC.IntC(x:1), ExprC.IntC(x: 2)])
let v2 = ExprC.IntA(x: values)

print(sizeofValue(values))
print(sizeofValue(v1))
print(sizeofValue(v2))

//RESULTS
//8
//8
//8

顺便说一句,这个结果出乎我的意料,我想象编码必须有额外的存储成本,所以我不确定这是否会在 F# 中发生。

【问题讨论】:

标签: memory f# overhead algebraic-data-types


【解决方案1】:

F# 编译器将 ADT 转换为 .NET 密封类层次结构。你的例子将被翻译成这样的东西(松散地说):

public class value {
  public class Dec : value { public int Item { get; } }
  public class Num : value { public int[] Item { get; } }
  public class Float : value { public double[] Item { get; } }
  public class Array : value { public value Item { get; } }
  public class Arr : value { public value[] Item { get; } }
}

除此之外,真的很难说,因为分配类的方式可能会因 VM 实现和底层机器架构而异。例如,在 x86/x64 上的 Windows 上的完整 .NET FW 上,对象将具有 32 位或 64 位对象标头以及对象的任何内容,可能是对齐的(请查看 this post 了解一些详细信息) .这意味着,例如,您的 Dec 案例将占用 8 或 12 个字节。

但是,其他 VM 实现可能会做不同的事情。 CoreCLR、Mono、MicroFW、.NET CF - 都可能对对象分配有自己的看法,.NET Native 编译器甚至可以完全优化整个事情。

这就是为什么 .NET 通常无法告诉您类的“大小”:通常,它不知道。想想看,谈论“大小”可能并不总是有意义的。 Swift 可以侥幸逃脱,因为它没有开放标准的虚拟机,所以它可以为所欲为。

如果您确实需要保证特定的内存布局,.NET 确实可以做到这一点(查找 StructLayoutAttribute),但它不适用于 ADT,这是可以理解的。

最后,我觉得你可能转移了注意力。为什么你想确切地知道这些事情?如果您真的关心内存占用,则根本不应该使用 F#(或 Swift),而应该使用 C(或者,如果您真的喜欢函数式编程,请查看 Rust)。否则,请记住“过早优化”。

【讨论】:

  • 我想知道,因为我会经常处理这个数组,并且不想使用 C 或 Rust。因此,如果我明白这一点,则开销仅用于额外的类,但实际数据保持相等
猜你喜欢
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 2014-08-15
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多