He oído mucho sobre el rendimiento increíble de los programas escritos en Haskell, y quería hacer algunas pruebas. Entonces, escribí una 'biblioteca' para las operaciones de la matriz simplemente para comparar su rendimiento con las mismas cosas escritas en puro C. Antes que nada, probé el rendimiento de multiplicación de 500000 matrices y noté que era ... interminable (es decir, terminando ¡con excepción de falta de memoria después de 10 minutos de eso)! Después de estudiar Haskell un poco más me las arreglé para deshacerme de la pereza y el mejor resultado que logré obtener es ~ 20 veces más lento que su equivalente en C. Entonces, la pregunta: ¿podría revisar el siguiente código y decir si su rendimiento puede mejorar un poco más? 20 veces todavía me decepciona un poco.ejecución de la matriz de ejecución haskell
import Prelude hiding (foldr, foldl, product)
import Data.Monoid
import Data.Foldable
import Text.Printf
import System.CPUTime
import System.Environment
data Vector a = Vec3 a a a
| Vec4 a a a a
deriving Show
instance Foldable Vector where
foldMap f (Vec3 a b c) = f a `mappend` f b `mappend` f c
foldMap f (Vec4 a b c d) = f a `mappend` f b `mappend` f c `mappend` f d
data Matr a = Matr !a !a !a !a
!a !a !a !a
!a !a !a !a
!a !a !a !a
instance Show a => Show (Matr a) where
show m = foldr f [] $ matrRows m
where f a b = show a ++ "\n" ++ b
matrCols (Matr a0 b0 c0 d0 a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3)
= [Vec4 a0 a1 a2 a3, Vec4 b0 b1 b2 b3, Vec4 c0 c1 c2 c3, Vec4 d0 d1 d2 d3]
matrRows (Matr a0 b0 c0 d0 a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3)
= [Vec4 a0 b0 c0 d0, Vec4 a1 b1 c1 d1, Vec4 a2 b2 c2 d2, Vec4 a3 b3 c3 d3]
matrFromList [a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3]
= Matr a0 b0 c0 d0
a1 b1 c1 d1
a2 b2 c2 d2
a3 b3 c3 d3
matrId :: Matr Double
matrId = Matr 1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
normalise (Vec4 x y z w) = Vec4 (x/w) (y/w) (z/w) 1
mult a b = matrFromList [f r c | r <- matrRows a, c <- matrCols b] where
f a b = foldr (+) 0 $ zipWith (*) (toList a) (toList b)
Su matriz 'mult' está cambiando representaciones entre matrices, listas y de nuevo a matrices. Si bien esto le permite hacer el cálculo en dos líneas de código, será muy, muy lento. –
@stephen tetley: no es necesariamente así.En la actualidad, los compiladores son bastante buenos en la creación de líneas y la deforestación, por lo que un compilador inteligente podría eludir las listas intermedias. En mis pruebas, esta implementación, en comparación con una multiplicación desenrollada a mano "rápida", no es terriblemente lenta (apenas 1,5 veces más lenta). UPD: mi error, en realidad 6 veces más lento para matrices dobles. –
A riesgo de ser etiquetado como un troll, no creo que encuentre resultados como los que está buscando con estas pruebas. En general, el mejor Haskell tendrá un rendimiento comparable con el buen C. Las grandes ventajas de Haskell provienen de la legibilidad, más expresividad en comparación con C y bibliotecas avanzadas como 'STM' y' parallel', que hacen que agregar paralelismo sea muy fácil en comparación con la mayoría otros idiomas. Para el trabajo numérico puro, es bastante difícil para el rendimiento de Haskell superar las implementaciones de C. –