【问题标题】:F# records vs .net structF# 记录与 .net 结构
【发布时间】:2011-08-17 01:03:33
【问题描述】:

f# 记录是否与 .net 结构相同?我看到人们谈论 f# struct,他们使用这个术语是否可以与 F# 记录互换?就像在FSharp runs my algorithm slower than Python 中一样,谈论使用结构作为字典键但使用代码type Tup = {x: int; y: int} 为什么这比上面链接中的元组作为字典键更快?

【问题讨论】:

标签: .net f#


【解决方案1】:

不,事实上,F# 中的记录类型是一种引用类型,只是具有特殊的函数式编程特性,例如属性的模式匹配、更简单的不变性和更好的类型推断。

我认为 Laurent 的加速肯定是其他原因,因为我们可以证明 Tup 不是 ValueType:

type Tup = {x: int; y: int}
typeof<Tup>.BaseType = typeof<System.Object> //true

type StructType = struct end
typeof<StructType>.BaseType = typeof<System.ValueType> //true
typeof<StructType>.BaseType = typeof<System.Object> //false

【讨论】:

  • 谢谢。 Laurent 的加速可能值得初学者提出一个新问题。我还不能评论这个问题。
  • @user8321,不客气。确实,我认为您应该为加速问题打开一个新问题。
  • 寻找此类问题答案的方法之一是使用反射器在 C# 中反汇编您的 F# 程序集,然后查看 F# 编译器发出的代码
  • 如果Struct属性应用于记录类型会怎样?
【解决方案2】:

正如斯蒂芬所说,它是一个引用类型。这是type Tup = {x: int; y: int}的编译代码(发布模式):

[Serializable, CompilationMapping(SourceConstructFlags.RecordType)]
public sealed class Tup : IEquatable<xxx.Tup>, IStructuralEquatable, IComparable<xxx.Tup>, IComparable, IStructuralComparable
{
    // Fields
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    internal int x@;
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    internal int y@;

    // Methods
    public Tup(int x, int y);
    ...

    // Properties
    [CompilationMapping(SourceConstructFlags.Field, 0)]
    public int x { get; }
    [CompilationMapping(SourceConstructFlags.Field, 1)]
    public int y { get; }
}

【讨论】:

  • 为什么这比 python 问题中作为字典键的元组更快?
【解决方案3】:

Stephen Swensen 是正确的,我想补充一个重要的细节,记录类型支持结构相等,.NET 的值类型也是如此,因此相等测试具有相似的行为(如果记录包含某些内容,则可能存在细微差别无法使用结构相等性进行比较)。

【讨论】:

    【解决方案4】:

    要回答问题的第二部分,实际上是将它们用作字典键。

    使用某物作为字典键的速度取决于GetHashCode 函数如何为该类型工作。对于 Records 等引用类型,默认的 .Net 行为使用Object.GetHashCode,它“根据对象的引用计算哈希码”,这是一种高效的数值运算。

    值类型的更复杂的默认行为,即结构是ValueType.GetHashCode “基类的方法使用反射来根据类型字段的值计算哈希码。” 所以结构越复杂,根据它的字段,计算哈希可能需要很多更长的时间。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多