F # записи против .net структура - PullRequest
11 голосов
/ 02 мая 2011

f # records - это то же самое, что .net struct?Я видел, как люди говорят о f # struct, они используют этот термин взаимозаменяемо с записями F #?Как и в FSharp запускает мой алгоритм медленнее, чем Python , говоря об использовании struct в качестве ключа словаря, но с кодом type Tup = {x: int; y: int} Почему это быстрее, чем кортеж в качестве ключа словаря в ссылке выше?

Ответы [ 4 ]

16 голосов
/ 02 мая 2011

Нет, фактически, тип записи в F # является ссылочным типом только со специальными функциями функционального программирования, такими как сопоставление с образцом по свойствам, более простая неизменность и лучший вывод типов.

Я думаю, что ускорение Лорана должно было бытьпо другим причинам, потому что мы можем доказать, что Tup не является типом значения:

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
4 голосов
/ 02 мая 2011

Как сказал Стивен, это ссылочный тип.Вот скомпилированный код (режим выпуска) 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; }
}
3 голосов
/ 02 мая 2011

Стивен Свенсен прав, я хотел бы добавить одну важную деталь: типы записей поддерживают структурное равенство, как и тип значений .NET, поэтому тесты на равенство ведут себя аналогично (могут быть тонкие различия, если запись содержит что-то это нельзя сравнить, используя структурное равенство).

2 голосов
/ 21 мая 2015

Чтобы ответить на вторую часть вопроса, речь идет об использовании их в качестве ключа словаря.

Скорость использования чего-либо в качестве словарного ключа сводится к тому, как функция GetHashCode работает для этого типа. Для ссылочных типов, таких как записи, стандартное поведение .Net использует Object.GetHashCode, который "вычисляет хеш-код на основе ссылки на объект" , которая является эффективной числовой операцией.

Более сложным поведением по умолчанию для типов значений, которое является структурой, является ValueType.GetHashCode "метод базового класса использует отражение для вычисления хеш-кода на основе значений полей типа." таким образом, чем сложнее структура и, в зависимости от ее полей, вычисление хэша может занять лот дольше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...