Over on Code Review, tôi đã trả lời một câu hỏi về naive Haskell fizzbuzz solution bằng cách đề xuất thực hiện iterates forward, tránh chi phí bậc hai của số nguyên tố ngày càng tăng và loại bỏ phân chia modulo (gần như) hoàn toàn. Đây là mã:Hiệu quả của unfoldr so với zipWith
fizz :: Int -> String
fizz = const "fizz"
buzz :: Int -> String
buzz = const "buzz"
fizzbuzz :: Int -> String
fizzbuzz = const "fizzbuzz"
fizzbuzzFuncs = cycle [show, show, fizz, show, buzz, fizz, show, show, fizz, buzz, show, fizz, show, show, fizzbuzz]
toFizzBuzz :: Int -> Int -> [String]
toFizzBuzz start count =
let offsetFuncs = drop (mod (start - 1) 15) fizzbuzzFuncs
in take count $ zipWith ($) offsetFuncs [start..]
Như một lời nhắc khác, tôi đề nghị viết lại bằng cách sử dụng Data.List.unfoldr
. Phiên bản unfoldr
là một sửa đổi đơn giản, rõ ràng đối với mã này vì vậy tôi sẽ không gõ nó ở đây trừ khi mọi người tìm cách trả lời câu hỏi của tôi nhấn mạnh rằng điều đó quan trọng (không có kẻ phá hoại cho OP trên Code Review). Nhưng tôi có một câu hỏi về hiệu quả tương đối của giải pháp unfoldr
so với zipWith
. Trong khi tôi không còn là một nhà khoa học Haskell nữa, tôi không có chuyên gia về nội bộ Haskell.
Giải pháp unfoldr
không yêu cầu danh sách vô hạn [start..]
vì nó chỉ có thể mở ra từ start
. Suy nghĩ của tôi là
- Giải pháp
zipWith
không ghi nhớ từng yếu tố liên tiếp của[start..]
khi được yêu cầu. Mỗi phần tử được sử dụng và loại bỏ vì không có tham chiếu đến phần đầu của [start ..] được giữ lại. Vì vậy, không có nhiều bộ nhớ được tiêu thụ ở đó hơn vớiunfoldr
. - Mối quan tâm về hiệu suất của
unfoldr
và các bản vá lỗi gần đây để làm cho nó luôn luôn được gạch chân được thực hiện ở cấp độ mà tôi chưa đạt được.
Vì vậy, tôi nghĩ hai điều này tương đương với mức tiêu thụ bộ nhớ nhưng không có ý tưởng về hiệu suất tương đối. Hy vọng thêm thông tin Haskellers có thể hướng dẫn tôi hướng tới một sự hiểu biết về điều này.
unfoldr
có vẻ là một điều tự nhiên để sử dụng để tạo chuỗi, ngay cả khi các giải pháp khác mang tính biểu cảm hơn. Tôi chỉ biết tôi cần hiểu thêm về hiệu suất thực tế của nó. (Đối với một số lý do tôi tìm foldr
dễ dàng hơn để hiểu ở mức độ đó)
Note: unfoldr
's sử dụng Maybe
là tiềm năng vấn đề biểu diễn đầu tiên đã xảy ra với tôi, trước khi tôi thậm chí bắt đầu điều tra vấn đề này (và các chỉ một chút về các cuộc thảo luận tối ưu hóa/nội tuyến mà tôi đã hiểu đầy đủ). Vì vậy, tôi đã có thể ngừng lo lắng về Maybe
ngay lập tức (được cung cấp một phiên bản gần đây của Haskell).
Bạn nên làm rõ rằng chi phí bạn đang nói đến đề cập đến việc tăng số lượng số nguyên tố. – dfeuer
@dfeuer Xong. Cảm ơn một lần nữa cho câu trả lời của bạn. – itsbruce