F#记录与.net结构

时间:2011-05-02 14:42:58

标签: .net f#

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

4 个答案:

答案 0 :(得分:16)

不,实际上,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

答案 1 :(得分:4)

斯蒂芬说,这是一种参考类型。以下是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; }
}

答案 2 :(得分:3)

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

答案 3 :(得分:1)

要回答问题的第二部分,它实际上是将它们用作字典键。 使用某些东西作为字典键的速度归结为GetHashCode函数如何适用于该类型。对于诸如Records之类的引用类型,默认的.Net行为使用Object.GetHashCode,它“根据对象的引用计算哈希码”,这是一种有效的数值运算。 值类型的更复杂的默认行为是结构类型,ValueType.GetHashCode“基类的方法使用反射来根据类型字段的值计算哈希码。”所以结构越复杂,并且根据其字段,计算哈希可能需要更长的时间。