【问题标题】:Haskell - converting from List to Data.VectorHaskell - 从 List 转换为 Data.Vector
【发布时间】:2012-11-16 01:37:11
【问题描述】:

在分析我的 haskell 程序后,我发现该程序中有 66% 的时间用于索引列表。该解决方案似乎正在使用 Data.Vector,但我在转换时遇到了麻烦:当我将代码更改为使用 Vector 时,它会使用大量内存,并且挂起得非常严重,我什至无法对其进行分析。这是什么原因造成的?

这是我要转换的文件:https://github.com/drew-gross/Blokus-AI/blob/master/Grid.hs

我尝试转换它:https://github.com/drew-gross/Blokus-AI/blob/convert-to-vector/Grid.hs

任何想法我做错了什么?或者至少,去哪里看?

【问题讨论】:

    标签: performance list haskell vector


    【解决方案1】:
    makeEmptyGrid width height defaultCell = Grid (Data.Vector.take arraySize $ fromList $ repeat defaultCell) width height
    

    那是一个杀手。 fromList 将整个列表转换为 Vector,但 repeat defaultCell 是一个无限列表。

    makeEmptyGrid width height defaultCell = Grid (fromListN arraySize $ repeat defaultCell) width height
    

    makeEmptyGrid width height defaultCell = Grid (fromList $ replicate arraySize defaultCell) width height
    

    会解决这个问题的。

    粗略查看其余部分并没有导致更明显的陷阱,但我可能很容易忽略了一些。

    【讨论】:

    • 谢谢!那个和另一个地方的同样问题解决了它。
    【解决方案2】:

    这只是 Daniel 的另一个想法。看起来你的Grids 只是Colors 它对于一个小的“网格”可能不会有太大的作用,但是为Color 创建一个Unbox 实例相对容易。然后一个网格将包含一个未装箱的数组。在Grid.hs 中,您将导入Data.Vector.Unboxed 而不是Data.Vector。由于许多原因,这通常好多更好,但需要您对许多定义添加Unbox a => 约束。如果您想制作或“映射”到充满除Color 之外的其他类型的东西的网格中,这可能会产生后果,除非它具有Unbox 实例。

    下面我只是添加了来自vector-th-unbox 的 TH 咒语(我最近才了解该软件包,并借此机会再次对其进行测试)和两个必要的定义。按照 Data.Vector.Unboxed.Base 中的 Bool 实例手动编写它不会难。

    {-#LANGUAGE TemplateHaskell, TypeFamilies, MultiParamTypeClasses#-}
    module Color where
    
    import Display
    import Data.Vector.Unboxed.Deriving 
    import qualified Data.Vector.Unboxed as V 
    import qualified Data.Vector.Generic         as G
    import qualified Data.Vector.Generic.Mutable as M 
    import Data.Word (Word8)
    
    data Color = Yellow | Red | Green | Blue | Empty      
               deriving (Show, Eq, Ord, Enum, Bounded)
    
    fromColor :: Color -> Word8
    {-# INLINE fromColor #-}
    fromColor = fromIntegral . fromEnum
    
    toColor :: Word8 -> Color
    {-# INLINE toColor #-}
    toColor x | x < 5 = toEnum (fromIntegral x)
    toColor _ = Empty
    
    derivingUnbox "Color"
       [t| Color -> Word8 |]
        [| fromColor |]
        [| toColor |]
    
    -- test
    colorCycle :: Int -> V.Vector Color
    colorCycle n = V.unfoldr colorop 0 where 
      colorop m  | m < n =  Just (toColor (fromIntegral (m `mod` 5)),m+1)
      colorop _ =  Nothing
    -- *Colour> colorCycle 12
    -- fromList [Yellow,Red,Green,Blue,Empty,Yellow,
    -- Red,Green,Blue,Empty,Yellow,Red]
    
    colorBlack  = "\ESC[0;30m"
    colorRed    = "\ESC[0;31m"
    colorGreen  = "\ESC[0;32m"
    colorYellow = "\ESC[0;33m"
    colorBlue =   "\ESC[0;34m"
    
    instance Display Color where
        display Red    = colorRed ++ "R" ++ colorBlack
        display Green  = colorGreen ++ "G" ++ colorBlack
        display Yellow = colorYellow ++ "Y" ++ colorBlack
        display Blue   = colorBlue ++ "B" ++ colorBlack
        display Empty  = "."
    

    编辑:在0.1 之前的vector-th-unbox 版本中,使用了以下模板:

    derivingUnbox "Color"
        [d| instance Unbox' (Color) Word8 |]
        [| fromColor |]
        [| toColor |]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-21
      • 2013-06-12
      • 2015-12-16
      • 2013-06-02
      • 2021-07-07
      相关资源
      最近更新 更多