- это записи f #, такие же как .net struct? Я видел, как люди говорили о f # struct, используют ли они этот термин для взаимозаменяемости с записями F #? Как и в FSharp запускает мой алгоритм медленнее, чем Python, говоря об использовании struct в качестве словарного ключа, но с кодом type Tup = {x: int; y: int}
Почему это быстрее, чем кортеж в качестве словарного ключа в ссылку выше?
Записи F # vs .net struct
Ответ 1
Нет, фактически, тип записи в F # является ссылочным типом только со специальными функциями функционального программирования, такими как сопоставление образцов по свойствам, более простая неизменность и лучший вывод типа.
Я думаю, что ускорение Лорана должно было быть по другим причинам, потому что мы можем доказать, что 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
Ответ 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 [email protected];
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal int [email protected];
// Methods
public Tup(int x, int y);
...
// Properties
[CompilationMapping(SourceConstructFlags.Field, 0)]
public int x { get; }
[CompilationMapping(SourceConstructFlags.Field, 1)]
public int y { get; }
}
Ответ 3
Стивен Свенсен прав, я хотел бы добавить одну важную деталь: типы записей поддерживают структурное равенство, также как и тип значений .NET, поэтому тесты равенства имеют аналогичное поведение (могут быть тонкие различия, если запись содержит что-то которые не могут сравниваться с использованием структурного равенства).
Ответ 4
Чтобы ответить на вторую часть вопроса, это действительно касается использования их в качестве словарного ключа.
Скорость использования чего-либо в качестве словарного ключа сводится к тому, как функция GetHashCode работает для этого типа. Для ссылочных типов, таких как записи, поведение по умолчанию .Net использует Object.GetHashCode
, который "вычисляет хэш-код на основе ссылки на объект", который является эффективной числовой операцией.
Более сложное поведение по умолчанию для типов значений, которое представляет собой метод struct ValueType.GetHashCode
"базового класса, использует отражение для вычисления хэш-кода на основе значений полей типа." поэтому чем сложнее структура и в зависимости от ее полей, вычисление хеша может занимать лот дольше.