Map.Map与函数

时间:2011-09-16 13:24:19

标签: haskell profiling

为什么在这种情况下使用数据构造函数和函数比使用字符串和Map要慢?

编辑:请注意我对Rotsor答案的第二次评论,它解释了为什么我接受了nulvinges的回答。

慢慢跑:

module Main where

import qualified Data.List as List

main :: IO ()
main = do
    print $ conspire fabFive fabFive

-- here i actually have 80 constructors
data Eris = Hera | Athene | Aphrodite | Paris | Helene
            deriving (Ord, Eq, Show, Read, Enum, Bounded)

fabFive = [minBound..maxBound] :: [Eris]

conspire :: [Eris] -> [Eris] -> [Eris]
conspire [Hera]   [Hera]   = [Hera, Athene]
...
conspire [Hera]   [Helene] = [Athene, Aphrodite, Paris]
...
conspire [Helene] [Helene] = [Hera]

conspire [a] (b:bs) =
    List.union (conspire [a] [b]) (conspire [a] bs)
conspire (a:as) ls =
    List.union (conspire [a] ls) (conspire as ls)

运行得更快:

module Main where

import qualified Data.Map as Map
import qualified Data.Set as Set

main :: IO ()
main = do 
    print $ conspire (Set.fromList fabFive) (Set.fromList fabFive)

fabFive = [ Hera, Athene, Aphrodite, Paris, Helene ]

conspire :: Set.Set String -> Set.Set String -> Set.Set String
conspire set1 set2 = Set.fold Set.union Set.empty $ Set.map
    (\x -> Set.fold Set.union Set.empty $ Set.map
        (\y -> conspiracy Map.! (Set.singleton x, Set.singleton y))
        set2
    )
    set1

conspiracy = Map.fromList
    [ ( (Set.singleton "Hera" , Set.singleton "Hera" )
      , Set.fromList [ "Hera", "Athene" ]
      )
    ...
    , ( (Set.singleton "Hera" , Set.singleton "Helene" )
      , Set.fromList [ "Athene", "Aphrodite", "Paris" ]
      )
    ...
    , ( (Set.singleton "Helene" , Set.singleton "Helene" )
      , Set.fromList [ "Hera" ]
      )
    ]

2 个答案:

答案 0 :(得分:4)

由于List.nub函数,您的第一个版本运行缓慢,效率非常低。它在O(N^2)时间内工作,N是列表的大小。对于大nub,其他所有内容都将由N支配。

答案 1 :(得分:-1)

Map创建一个O(1)的散列映射,但是使用函数你必须检查每个条件。

编辑:这实际上是错误的。 Map是一个大小平衡的二叉树,但这应该会导致O(logn)复杂性,而函数必须检查每个组合,因此具有O(n)复杂度。

记住模式匹配的工作原理:

f 0 = 0
f i = 1+f (i-1)

是语法糖:

f i = if i == 0
      then 0
      else 1+f (i-1)

您正在进行O(n)比较,以找到您要执行的功能。

使用Map,它在二叉树中进行搜索,只需进行O(logn)比较。