'IEquatable in F#, = operator performance and structural equality

I'm wondering in which cases equality tests in F# cause boxing, and whether there are cases in which overriding Equals and GetHashCode and implementing IEquatable<> is preferable to using the StructuralEqualityAttribute. If so, can it be done without reducing the performance of the = operator?

For simple structs holding one integer, I ran a loop that repeats the same equality check 1M times. I timed the loop using...

  • = with custom (type and value test) equality: about 110ms
  • = with structural equality: 20ms to 25ms
  • A custom == operator that redirects to IEquatable: 1ms to 3ms
  • A custom == operator that compares the values directly: 0ms (erased by optimizer)

From what I understand, the IEquatable<> interface can be used as a performance optimization to prevent boxing when checking for equality. This seems to be common in C#, but I can hardly find mentions of it in F#. Also, the F# compiler complains when trying to override the = operator for a given type.

The StructuralEquality attribute is documented in the MSDN to override only Equals and GetHashCode. Still, it does prevent the explicit implementation of IEquatable<>. However, the resulting type is incompatible with IEquatable<MyType>. This doesn't seem logical to me, should a structurally equated type not implement IEquatable<>?

There is a note on the performance of = in the F# specification (8.15.6.2 in the 3.0 spec), but I don't know what to make of it:

Note: In practice, fast (but semantically equivalent) code is emitted for direct calls to (=), compare, and hash for all base types, and faster paths are used for comparing most arrays

The definition of "base types" given before doesn't seem useful to read this note. Does this refer to basic types?

I'm confused. What is going on? What would a proper equality implementation look like, if the type might be used as a collection key or in a frequent equality test?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source