2012-11-16 50 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 |]