, я делал довольно неудачные попытки решить проблему PRIME1 на SPOJ. Я обнаружил, что использование ByteString действительно помогает производительности при чтении текста проблемы. Однако использование ByteString для записи результатов на самом деле немного медленнее, чем использование функций Prelude. Я пытаюсь понять, делаю ли я это неправильно или этого ожидаемо.
Я провел профилирование и тайминг, используя (putStrLn.show) и эквиваленты ByteString тремя разными способами:
Я провел профилирование и тайминг, используя (putStrLn.show) и эквиваленты ByteString тремя разными способами:
Я провел профилирование и тайминг, используя (putStrLn.show) и эквиваленты ByteString тремя разными способами:
Я ожидал, что числа 2 и 3 будут работать медленнее, поскольку вы создаете список в одной функции и используете его в другой. Распечатывая числа по мере их создания, я избегаю выделения памяти для списка. С другой стороны, вы выполняете системный вызов call с каждым вызовом putStrLn. Правильно? Итак, я протестировал, и на самом деле №1 оказался самым быстрым.
Наилучшая производительность была достигнута с вариантом №1 и функциями Prelude ([Char]). Я ожидал, что моей лучшей производительностью будет вариант №1 с ByteString, но этого не произошло. Я использовал только ленивые ByteStrings, но не думал, что это имеет значение. Может?
Некоторые вопросы:
Моя рабочая гипотеза заключается в том, что запись Integer с ByteString происходит медленнее, если вы не объединяете их с другим текстом. Если вы комбинируете целые числа с [Char], тогда вы получите лучшую производительность при работе с ByteStrings. Т.е. перезапись ByteString:
putStrLn $ "the answer is: " ++ (show value)
будет намного быстрее, чем версия, написанная выше. Это правда?
Спасибо за чтение!