2012-11-16 18 views
5

在分析我的haskell程序后,我发现程序中有66%的时间花费在索引列表中。该解决方案似乎使用Data.Vector,但我遇到了转换问题:当我更改代码以使用Vector时,它使用了大量内存,并且挂起很严重,甚至无法对其进行配置。什么会造成这种情况?Haskell - 从列表转换为Data.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

任何想法我做错了吗?或者至少,在哪里看?

回答

6
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 

会解决这个问题。

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

+0

谢谢!这在另一个地方解决了这个问题。 – Drew

5

这只是丹尼尔之后的另一种想法。它看起来像你的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 = "." 

编辑:在vector-th-unbox版本0.1以下模板前使用:

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