2012-09-10 47 views
9

Đây là một ví dụ từ Tìm hiểu bạn một Haskell:Haskell - Danh sách Hiểu vị từ Optimization

ghci> [ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50] 
[55,80,100,110] 

Vì vậy, những gì đang xảy ra ở đây, sẽ x*y được tính hai lần hoặc một lần?

+6

Điều đó tùy thuộc vào trình biên dịch. – augustss

+4

Để đưa ra giải pháp thay thế khác là Haskell đẹp hơn IMO so với Mog, hãy xem xét 'bộ lọc (> 50) [x * y | x <- [2,5,10], y <- [8,10,11]] ' – leftaroundabout

Trả lời

18

Để chắc chắn về hành vi của trình biên dịch, thích:

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

Tuy nhiên, điều này còn sạch hơn nhiều. – GManNickG

21

Nó sẽ được tính hai lần trừ khi loại bỏ subexpression chung xảy ra.

Tùy thuộc vào nội tuyến và mức tối ưu hóa của bạn, GHC có thể làm những điều khá tích cực với việc hiểu danh sách.

Nói chung, bạn nên chia sẻ rõ ràng các biểu thức chung để đảm bảo chia sẻ.

7

Nhìn vào cốt lõi khi biên soạn với -O2 tùy chọn nó đã đường (có liên quan và đơn giản) sau

  case (y_aAD * sc_s1Rq) > 50 of 
      False -> go_XB2 sc1_s1Rr; 
      True -> (y_aAD * sc_s1Rq):(go_XB2 sc1_s1Rr) 

này rõ ràng cho thấy rằng nhân được tính hai lần, vì vậy nó là sử dụng tốt hơn biểu hiện thông thường để ngăn chặn tính toán lại .

Các vấn đề liên quan