is f# records is the same as .net struct? I saw people talk about f# struct,are they use this term interchangable with F# records? Like in FSharp runs my algorithm slower than Python, talking about using struct as dictionary key but with code type Tup = {x: int; y: int}
Why is this faster than a tuple as a dictionary key in the link above?
-
i asked a similar question on how to use the .net structs from f#: http://stackoverflow.com/questions/4855766/how-to-use-c-struct-from-f – Alex May 05 '11 at 14:18
4 Answers
No, in fact, a record type in F# is a reference type just with special functional programming features like pattern matching on properties, easier immutability, and better type inference.
I think Laurent's speedup must have been for other reasons, because we can prove that Tup
is not a ValueType:
type Tup = {x: int; y: int}
typeof<Tup>.BaseType = typeof<System.Object> //true
Whereas
type StructType = struct end
typeof<StructType>.BaseType = typeof<System.ValueType> //true
typeof<StructType>.BaseType = typeof<System.Object> //false

- 22,107
- 9
- 81
- 136
-
Thanks. Laurent's speedup may deserve a new question for beginner. I just cannot comment on that question yet. – user8321 May 02 '11 at 15:07
-
@user8321, you're welcome. Verily, I think you should open a new question for the speedup question. – Stephen Swensen May 02 '11 at 15:19
-
2On of the way to find answer to such questions is to use reflector to disassemble your F# assembly in C# and see what code is emitted by F# compiler – Ankur May 03 '11 at 04:10
-
To answer the second part of the question, it's really about using them as a dictionary key.
The speed of using something as a dictionary key comes down to how the GetHashCode function works for that type. For reference types such as Records, the default .Net behaviour uses Object.GetHashCode
which "computes the hash code based on the object's reference" which is an efficient numeric operation.
The more complex default behaviour for value types, which is what structs are is ValueType.GetHashCode
"method of the base class uses reflection to compute the hash code based on the values of the type's fields." so the more complex the struct and depending on its fields, computing the hash could take a lot longer.

- 17,578
- 6
- 88
- 115
-
1For .NET structs that will be used as keys in a Dictionary, it is crucial to implement both IEquatable
and your own GetHashCode() - the default implementations for structs might make them 10x slower. Also see http://blogs.msdn.com/b/jaredpar/archive/2009/01/15/if-you-implement-iequatable-t-you-still-must-override-object-s-equals-and-gethashcode.aspx – Govert May 21 '15 at 14:51
As Stephen said, it is a reference type. Here is the compiled code(release mode) of 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; }
}

- 16,980
- 13
- 75
- 117
-
2why is this faster than a tuple as dictionary key as in the python question? – user8321 May 02 '11 at 15:09
Stephen Swensen is correct, I'd like to add one important detail, Record Types support structural equality, as do .NET’s value type, so there equality tests have the similar behavior (there may be subtle differences if a record contains something that can’t be compared using structural equality).

- 6,407
- 2
- 34
- 41