Đâ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?
Đâ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?
Để 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]
Tuy nhiên, điều này còn sạch hơn nhiều. – GManNickG
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ẻ.
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 .
Điều đó tùy thuộc vào trình biên dịch. – augustss
Để đư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