2015-10-07 1 views
3

Мы в основном используем данные для хранения значений, например:Как быстро сопоставляется шаблон Haskell?

data Sex = Male | Female 
data Person = Person {name :: String, age :: Int, sex :: Sex} 

charlie :: Person 
charlie = Person "Charlie" 32 Male 

И теперь у нас есть хорошие функции nameage и sex, чтобы получить значение данных с.

Но, с GADTs и Rank2, мы можем сделать что-то прохладнее:

{-# LANGUAGE GADTs  #-} 
{-# LANGUAGE Rank2Types #-} 

data Sex = Male | Female 

data Data a where 
    Name :: Data String 
    Age :: Data Int 
    Sex :: Data Sex 

type Person = forall a. Data a -> a 

charlie :: Person 
charlie Name = "Charlie" 
charlie Age = 32 
charlie Sex = Male 

Итак, это чертовски удивительным. Это дает нам великолепный синтаксис для определения людей и делает использование GADT гладким.

Но разве это действительно лучше? Как это отображается во время выполнения? Является ли сопоставление шаблонов на самом деле медленнее и/или больше в представлении, чем данные?

lt; dr: Как быстро сопоставляется образец по сравнению с поиском данных?

+3

Я думаю, YMMV о том, является ли это полезным использованием GADT. Тем не менее, совпадение шаблонов - это самая быстрая вещь: все остальное зависит от нее (за исключением таких вещей, как математика с плавающей запятой). Что касается «поиска данных» (полевые помощники), вы можете посмотреть на ядро, чтобы увидеть, что они на самом деле делают. –

+4

Попробуй и посмотри! Но я бы предсказал примерно на порядок замедление по сравнению с использованием данных. Но это связано скорее с накладными расходами на вызов неизвестной функции, чем из-за соответствия шаблонов. Версия функции также не совсем то же самое, потому что если поля являются более сложными выражениями, чем просто '32', они будут пересматриваться каждый раз. (Или вы или компилятор выталкиваете его из функции в закрытие, а затем просто заново изобретаете хранение данных в виде данных с дополнительными служебными данными для доступа к нему.) –

+6

Проблема с представлением '(->) состоит в том, что обновление полей пространство утечек и поиск замедляются после каждого обновления. –

ответ

3

Если вы скомпилируете свой код с помощью -ddump-asm, вы можете увидеть совпадение шаблонов - это серия сравнений и прыжков с данными, встроенными в инструкции (загрузите адрес для строки, загрузите константу для числа 32 и т. Д.).

Контейнер, такой как Карта или HashMap, будет медленнее из-за косвенности, но, надеюсь, очевидно, что статически называемая переменная быстрее, чем перемещение (потенциально динамическая) древовидной структуры.