В обзоре Code я ответил на вопрос о naive Haskell fizzbuzz solution, предложив реализацию, которая iterates forward, избегая квадратичной стоимости растущего числа простых чисел и полностью отбрасывая модульное деление (почти). Вот код:Эффективность unoldr по сравнению с 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..]
Как еще подскажите, я предложил переписывать его с помощью Data.List.unfoldr
. Версия unfoldr
является очевидной, простой модификацией этого кода, поэтому я не буду вводить ее здесь, если люди, которые хотят ответить на мой вопрос, не настаивают на важности (никаких спойлеров для OP над обзором кода). Но у меня есть вопрос об относительной эффективности решения unfoldr
по сравнению с zipWith
. Хотя я уже не неофит Хаскелла, я не являюсь экспертом в области Haskell.
Решение unfoldr
не требует бесконечного списка [start..]
, так как он может просто развернуться от start
. Мои мысли
zipWith
решение не memoize каждый последующий элемент[start..]
, как он просил. Каждый элемент используется и отбрасывается, поскольку не сохраняется ссылка на главу [start ..]. Таким образом, больше нет памяти, чем сunfoldr
.- Проблемы, связанные с производительностью
unfoldr
, и последние исправления, чтобы сделать его всегда вложенным, проводятся на уровне, который я еще не достиг.
Таким образом, я думаю, что эти два эквивалента в потреблении памяти, но не имеют представления об относительной производительности. Надеясь, что более информированные Хаскеллеры могут направить меня к пониманию этого.
unfoldr
Кажется естественным, что нужно использовать для генерации последовательностей, даже если другие решения более выразительны. Я просто знаю, что мне нужно больше понять, что это реальная производительность. (По некоторым причинам я считаю foldr
гораздо легче понять на этом уровне)
Примечание: unfoldr
«s использование Maybe
был первым потенциальная проблема производительности, которая пришла мне в голову, прежде чем я даже начал исследовать этот вопрос (и только бит обсуждений по оптимизации/вставке, которые я полностью понял). Поэтому я сразу же смог перестать беспокоиться о Maybe
(учитывая недавнюю версию Haskell).
Вы должны уточнить, что стоимость, о которой вы говорите, относится к увеличению количества простых чисел. – dfeuer
@dfeuer Выполнено. Еще раз спасибо за ваш ответ. – itsbruce