Мне нужно отсортировать строки больших целых матриц в Haskell, и я начал проводить сравнительный анализ со случайными данными. Я обнаружил, что Haskell в 3 раза медленнее, чем C++.Haskell: сортировка матриц намного медленнее, чем сортировка по вектору
Из-за случайности, я ожидаю, что сравнение строк всегда заканчивается в первом столбце (который не должен иметь дубликатов). Поэтому я сузил матрицу до одного столбца, реализованного как вектор (Unboxed.Vector Int), и сравнил его сортировку с обычным Vector Int.
Vector Int сортируется так же быстро, как C++ (хорошие новости!), Но опять же, матрица столбцов в 3 раза медленнее. У вас есть идея, почему? Пожалуйста, найдите код ниже.
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
Это может быть просто бокс. Попробуйте его на C++ как массив указателей на отдельные выделенные строки, а не на многомерный массив (я предполагаю здесь) и сравниваю. Я не думаю, что многомерные векторы поддерживаются, поэтому, если это то, что происходит, вам придется немного обработать абстракцию, чтобы представить матрицы как векторы размера n * m. – luqui
Основываясь на @luqui, многомерные массивы C++ по-прежнему являются одним непрерывным блоком в памяти, а здесь у вас есть вектор ссылок на распакованные векторы. Я ожидаю, что вы получите значительно лучшую производительность, если вы использовали ['array'] (https://hackage.haskell.org/package/array) или [' repa'] (https://hackage.haskell.org/package/репа). – Alec
Я сравниваю с std :: vector> в C++, так же, как Vector (Vector Int) в Haskell, то есть вектор указателей на векторы. Я думал о том, чтобы упаковать мою матрицу в виде Vector Int размером n * m, но тогда у меня нет никакого вида, который мог бы сразу менять блоки Ints. И даже если бы у меня был этот обмен блоком, я думаю, он был бы менее эффективен, чем сортировка указателей на векторы (слишком много записей в памяти). –