5

在分析我的 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

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

4

2 回答 2

7
makeEmptyGrid width height defaultCell = Grid (Data.Vector.take arraySize $ fromList $ repeat defaultCell) width height

那是一个杀手。fromList将整个列表转换为 a 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

会解决这个问题。

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

于 2012-11-16T02:11:45.010 回答
5

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

下面我只是添加了 TH 咒语vector-th-unbox(我最近刚刚了解了那个包,并借此机会再次测试它)和两个必要的定义。在Data.Vector.Unboxed.Base.

{-#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 |]
于 2012-11-16T17:57:58.383 回答