Является ли построение функции Haskell из словаря (Data.Map.Strict.Map) неэффективным? - PullRequest
0 голосов
/ 05 марта 2020

У меня есть функция, которая преобразует Map kv (из Data.Map.Strict в контейнеры ) в обычную функцию (k -> v). Код имеет следующую форму:

import qualified Data.Map.Strict as Map

funcFromMap :: (Ord k) => Map.Map k v -> k -> v
funcFromMap map = (\k -> fromMaybe (error "error message") $ Map.lookup k map)

Когда я запускаю свое приложение с профилированием времени, эта функция занимает первое место с общим временем ~ 40%. Это удивительно, потому что он вызывается только в результате фолда, который выполняет динамические вычисления программирования c, которые, как я ожидаю, будут значительно дороже, чем funcFromMap. Является ли написание функции вышеупомянутой формы вообще плохой идеей по какой-то причине?

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

1 Ответ

3 голосов
/ 05 марта 2020

Обратите внимание, что вы не превращаете Map в функцию. Вы превращаете функцию (а именно Map.lookup) в другую функцию. Haskell программирование - это превращение функций в другие функции, поэтому если бы это было неэффективно, у всех нас было бы много проблем!

Короче говоря, с funcFromMap нет ничего плохого (за исключением того, что уже существует как функция (!), как указывало @chi), и нет причин, по которым она должна быть неэффективной.

Во-первых, убедитесь, что вы читаете «отдельный» столбец вместо «унаследованного» столбец в выводе профиля. «Индивидуальный» столбец показывает время, фактически потраченное на саму функцию.

Если в «индивидуальном» столбце действительно указано 40%, то получается, что lookup встроен в ваш funcFromMap, и по какой-то причине фактические поиски на карте очень дороги в вашем приложении. Я думаю, что нам нужно увидеть минимальный пример, иллюстрирующий проблему, чтобы сказать, почему.

...