Ho sentito parlare molto delle prestazioni sorprendenti dei programmi scritti in Haskell e volevo fare alcuni test. Quindi, ho scritto una "libreria" per le operazioni con le matrici solo per confrontare le sue prestazioni con le stesse cose scritte in puro C. Prima di tutto ho testato le prestazioni di moltiplicazione delle matrici 500000, e ho notato che era ... senza fine (es. con eccezione di memoria esaurita dopo 10 minuti circa)! Dopo aver studiato haskell un po 'di più sono riuscito a liberarmi della pigrizia e il risultato migliore che sono riuscito a ottenere è ~ 20 volte più lento del suo equivalente in C. Quindi, la domanda: potresti rivedere il codice qui sotto e dire se le sue prestazioni possono essere migliorato un po 'di più? 20 volte mi sta ancora deludendo un po '.prestazioni di implemetazione della matrice 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)
vostra matrice 'mult' sta cambiando rappresentazioni tra matrici, liste e torna a matrici. Mentre questo ti permette di fare il calcolo in due righe di codice, sarà molto, molto lento. –
@stephen tetley: non è necessariamente così.Al giorno d'oggi i compilatori sono piuttosto abili nell'inlining e nella deforestazione, quindi un compilatore intelligente eliderebbe le liste intermedie. Nei miei test questa implementazione, rispetto a una moltiplicazione "veloce" scritta a mano, non è terribilmente lenta (solo circa 1,5 volte più lenta). UPD: il mio errore, in realtà 6 volte più lento per le matrici doppie. –
A rischio di essere etichettato come un troll, non penso che con questi test troverai risultati come quelli che stai cercando. Generalmente il migliore Haskell darà prestazioni al pari di C. buono. I grandi vantaggi di Haskell derivano dalla leggibilità, più espressività rispetto a C e librerie avanzate come 'STM' e' parallel', che rendono l'aggiunta del parallelismo molto facile rispetto alla maggior parte altre lingue. Per il puro lavoro numerico, è abbastanza difficile per le prestazioni di Haskell superare le implementazioni di C. –