Performance Haskell:矩阵排序比向量排序慢得多
我必须对Haskell中的大整数矩阵行进行排序,并开始使用随机数据进行基准测试。我发现Haskell比C++慢3倍。 由于随机性,我希望行比较总是在第一列终止(应该没有重复项)。因此,我将矩阵缩小为一个实现为向量(unbox.Vector Int)的列,并将其排序与通常的向量Int进行比较 向量int和C++一样好(好消息!),但同样,列矩阵是3倍慢。你知道为什么吗?请在下面查找代码Performance Haskell:矩阵排序比向量排序慢得多,performance,sorting,haskell,matrix,Performance,Sorting,Haskell,Matrix,我必须对Haskell中的大整数矩阵行进行排序,并开始使用随机数据进行基准测试。我发现Haskell比C++慢3倍。 由于随机性,我希望行比较总是在第一列终止(应该没有重复项)。因此,我将矩阵缩小为一个实现为向量(unbox.Vector Int)的列,并将其排序与通常的向量Int进行比较 向量int和C++一样好(好消息!),但同样,列矩阵是3倍慢。你知道为什么吗?请在下面查找代码 import qualified Data.Vector.Unboxed as UV(Vector, fromL
import qualified Data.Vector.Unboxed as UV(Vector, fromList)
import qualified Data.Vector as V(Vector, fromList, modify)
import Criterion.Main(env, bench, nf, defaultMain)
import System.Random(randomIO)
import qualified Data.Vector.Algorithms.Intro as Alg(sort)
randomVector :: Int -> IO (V.Vector Int)
randomVector count = V.fromList <$> mapM (\_ -> randomIO) [1..count]
randomVVector :: Int -> IO (V.Vector (UV.Vector Int))
randomVVector count = V.fromList <$> mapM (\_ -> do
x <- randomIO
return $ UV.fromList [x]) [1..count]
benchSort :: IO ()
benchSort = do
let bVVect = env (randomVVector 300000) $ bench "sortVVector" . nf (V.modify Alg.sort)
bVect = env (randomVector 300000) $ bench "sortVector" . nf (V.modify Alg.sort)
defaultMain [bVect, bVVect]
main = benchSort
import qualified Data.Vector.unbox为UV(Vector,fromList)
导入符合条件的数据。矢量为V(矢量,从列表,修改)
导入标准.Main(环境、工作台、nf、defaultMain)
导入系统随机(随机)
将限定数据.Vector.Algorithms.Intro导入为Alg(排序)
随机向量::Int->IO(V.Vector Int)
randomVector count=V.fromList mapM(\ \ \ \->randomIO)[1..count]
randomVVector::Int->IO(V.Vector(UV.Vector Int))
randomVVector count=V.fromList mapM(\ \ \ \->do
XFP的建议,实现向量作为一个<代码>数组AysAR[比矢量(Unboxed.Vector Int)快4倍,比排序C++ 40%代码慢:STD::矢量< /代码>:
例如,对整数矩阵排序将使用
sortIntArrays :: ByteArray -> ByteArray -> Ordering
sortIntArrays x y = let h1 = indexByteArray x 0 :: Int
h2 = indexByteArray y 0 :: Int in
compare h1 h2
正如Edward Kmett向我解释的那样,Haskell版本有一个额外的间接层
data Vector a = Vector !Int !Int ByteArray#
向量的每个条目实际上是指向一个记录保持切片索引和指向一个字节数组的指针。这是C++代码没有的间接方向。解决方案是使用<代码>数组AARYARAMEL ,它是指向字节数组的直接指针数组,或者是进一步的<代码>数组AARYARCHON/<代码>。EDE <代码>向量,您必须了解切片机的操作方法。另一种选择是切换到原始/<代码>,它提供了更简单的数组。< /P>它可能只是拳击。在C++中尝试它作为指向单独分配行的指针数组,而不是多维数组(我假设这里)。我不认为多维向量是支持的,所以如果这是什么,你必须做一点抽象工作来表示矩阵作为n*m的向量,在@ LuQUI上构建,C++多维数组仍然是内存中的一个连续块,而这里有一个引用向量的向量。如果你使用了或者,我会得到更好的性能。我与STD::C++中的向量进行比较,所以与向量(向量int)相同。在Haskell中,即指向向量的指针向量。我曾想过将我的矩阵打包为大小为n*m的向量Int,但我没有可以一次交换Int块的排序。即使我进行了块交换,我想它也不如对指向向量的指针进行排序(内存中写入太多)有效。Haskell仍然有一个额外的指向未绑定向量的间接方法。Edward Kmett通过使用unsafeccoerce
(注意#
)直接插入指针,而不是在指针周围放入包装器,获得了很好的结果。
data Vector a = Vector !Int !Int ByteArray#