Arrays 在Haskell中初始化不可变的unboxed int数组的最快方法是什么?
这是在Haskell中用非默认(非零)值初始化不可变数组的最快方法吗?在下面的示例中,我只是用0到(size-1)的值初始化数组 迄今为止最快的(速度是下面Code.ST的两倍)。感谢leftaroundabout: 我原来最快的:Arrays 在Haskell中初始化不可变的unboxed int数组的最快方法是什么?,arrays,haskell,Arrays,Haskell,这是在Haskell中用非默认(非零)值初始化不可变数组的最快方法吗?在下面的示例中,我只是用0到(size-1)的值初始化数组 迄今为止最快的(速度是下面Code.ST的两倍)。感谢leftaroundabout: 我原来最快的: module Code.ST where import Data.Array.MArray import Data.Array.ST import Data.Array.Unboxed stArray :: Int -> UArray Int Int st
module Code.ST where
import Data.Array.MArray
import Data.Array.ST
import Data.Array.Unboxed
stArray :: Int -> UArray Int Int
stArray size =
runSTUArray $ newArray (0,size-1) 0 >>= f 0
where
f i a
| i >= size = return a
| otherwise = writeArray a i i >> f (i + 1) a
stMain :: IO ()
stMain = do
let size = 340000000
let a = stArray size
putStrLn $ "Size: " ++ show size ++ " Min: " ++ show (a ! 0) ++ " Max: " ++ show (a ! (size - 1))
我尝试过更简单的不可变方法,在我的电脑(YMMV)上速度慢了2到3倍。我也尝试过Repa,但即使是小于3400000000大小的阵列,它也会失败(很多HD垃圾-我在它完成之前就放弃了)。您是否尝试过
Data.Array.unbox
中的listArray
?您可以这样使用它们:
-- listArray :: (Ix i, IArray a e) => (i, i) -> [e] -> a i e
listArray (0,3) "abcdefgh" :: UArray Int Char
这将产生
array (0,3) [(0,'a'),(1,'b'),(2,'c'),(3,'d')]
如果您需要更大的灵活性,可以使用同一模块中的array
-- array :: (Ix i, IArray a e) => (i, i) -> [(i, e)] -> a i e
array (0,3) (zip [1,3,0,2] "abcd") :: UArray Int Char
那会产生什么
array (0,3) [(0,'c'),(1,'a'),(2,'d'),(3,'b')]
我真的不知道它是否快,但肯定它比手写的ST循环更方便。我认为最快的方法是切换到
Data.Vector.unbox
,简单地stArray size=generate size id
。leftaroundabout:是的,你是对的。Data.Vector.unbox的速度是前者的两倍。如果你把它变成一个,我会接受你的答案:-)Data.Vector.unbox.generate如何比较?是的,我试过了,listArray的速度慢了2到3倍。我宁愿不写ST循环,但在这种情况下,速度比方便更重要。在我的机器上,你用listArray
编写的示例只比ST慢1.5倍左右。它肯定不会慢两倍它在我的电脑上:-)实际数字很大程度上取决于您的特定CPU、CPU缓存大小、内存大小/速度等。
array (0,3) [(0,'c'),(1,'a'),(2,'d'),(3,'b')]