从字典(Data.Map.Sstrict.Map)构建Haskell函数是否效率低下



我有一个函数,它将Map k v(来自容器中的Data.Map.String(转换为常规函数(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%左右。这是令人惊讶的,因为它只在执行动态编程计算的fold的结果时被调用,我认为这比funcFromMap要贵得多。出于某种原因,写上面形式的函数通常是个坏主意吗?

p.s:我的其余代码旨在避免查找映射中没有的键,所以我认为这个实现至少应该是安全的。

请注意,您并没有将Map转换为函数。您正在将一个函数(即Map.lookup(转换为另一个函数。Haskell编程就是把函数变成其他函数,所以如果效率低下,我们都会遇到很多麻烦!

简而言之,funcFromMap没有任何问题(除了它已经作为函数(!)存在,正如@chi所指出的(,它没有理由效率低下。

首先,确保在概要文件输出中读取的是"单独"列,而不是"继承"列。"个人"列给出了函数本身实际花费的时间。

如果"单个"列真的表示40%,那么实际发生的情况是lookup已经内联到funcFromMap中,并且由于某种原因,实际的映射查找在应用程序中非常昂贵。我认为我们需要看到一个最小的例子来说明问题的原因。

最新更新