Tôi có sau đây, câu nói cửa miệng mã cho việc tính toán số Fibonacci thứ n trong Haskell:Non-pointfree phong cách là chậm hơn đáng kể
fibonacci :: Int -> Integer
fibonacci = (map fib [0..] !!)
where fib 0 = 0
fib 1 = 1
fib n = fibonacci (n-2) + fibonacci (n-1)
Sử dụng này, tôi có thể làm các cuộc gọi như:
ghci> fibonacci 1000
và nhận câu trả lời gần như tức thời.
Tuy nhiên, nếu tôi sửa đổi các mã trên để nó không có trong phong cách pointfree, ví dụ:
fibonacci :: Int -> Integer
fibonacci x = (map fib [0..] !!) x
where fib 0 = 0
fib 1 = 1
fib n = fibonacci (n-2) + fibonacci (n-1)
nó là chậm hơn đáng kể. Trong phạm vi cuộc gọi như
ghci> fibonacci 1000
treo cứng.
Sự hiểu biết của tôi là hai đoạn mã trên tương đương nhau, nhưng GHCi cầu xin sự khác biệt. Có ai có một lời giải thích cho hành vi này?
Định nghĩa đầu tiên giống như 'fibonacci = let k = map fib [0 ..] trong \ x -> k !! x'. Nó có thể chia sẻ danh sách kết quả thay vì phải tính toán lại mỗi lần. – melpomene
Mm, vì vậy tôi hài lòng với nội dung "chia sẻ" này (ghi nhớ) làm cho người đầu tiên cực nhanh. Nhưng tại sao lại làm tương tự cho cái thứ hai? – MadMonty
Bạn đang chạy mã của mình trong GHCI mà không cần tối ưu hóa. Hãy thử biên dịch cả hai hàm bằng '-O2' và xem liệu GHC có đủ thông minh để giải quyết vấn đề của bạn cho bạn hay không. – user2407038