To jest przykład z Dowiedz się państwu Haskell:Haskell - Optymalizacja Lista Rozumienie predykaty
ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]
[55,80,100,110]
Więc, co się dzieje na naszym x*y
być obliczana dwa razy lub raz?
To jest przykład z Dowiedz się państwu Haskell:Haskell - Optymalizacja Lista Rozumienie predykaty
ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]
[55,80,100,110]
Więc, co się dzieje na naszym x*y
być obliczana dwa razy lub raz?
Aby mieć pewność zachowania kompilatora, wolą:
[ product | x <- [2, 5, 10]
, y <- [8, 10, 11]
, let product = x * y
, product > 50]
To i tak jest znacznie czystsze. – GManNickG
byłoby obliczane dwa razy, chyba że zachodzi eliminacja wspólny podwyrażenie.
zależności inline i poziomu optymalizacji GHC można zrobić dość agresywne rzeczy z listy zrozumieniem.
W ogóle, należy wyraźnie wspólne wyrażeń zagwarantować udostępnianie.
Patrząc w rdzeniu gdy skompilowany z opcją -O2 to następujące linie (właściwych i uproszczonych)
case (y_aAD * sc_s1Rq) > 50 of
False -> go_XB2 sc1_s1Rr;
True -> (y_aAD * sc_s1Rq):(go_XB2 sc1_s1Rr)
To wyraźnie pokazuje, że mnożenie jest obliczana dwa razy, więc jest lepsze wykorzystanie wspólnego wyrażenie zapobiegać Przeliczenie .
To zależy od kompilatora. – augustss
Aby nadać inną alternatywę, która jest IMO ładniejszy niż Haskell Mog trzeba brać pod uwagę 'filtr (> 50) [x * y | x <- [2,5,10], y <- [8,10,11]] ' – leftaroundabout