2012-09-10 11 views
9

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?

+6

To zależy od kompilatora. – augustss

+4

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

Odpowiedz

18

Aby mieć pewność zachowania kompilatora, wolą:

[ product | x <- [2, 5, 10] 
      , y <- [8, 10, 11] 
      , let product = x * y 
      , product > 50] 
+0

To i tak jest znacznie czystsze. – GManNickG

21

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.

7

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 .