Когда я использую ByteString, а когда нет? - PullRequest
24 голосов
/ 12 мая 2011

Я делал довольно неудачные попытки решить проблему PRIME1 на SPOJ.Я обнаружил, что использование ByteString действительно помогло повысить производительность при чтении текста проблемы.Однако использование ByteString для записи результатов на самом деле немного медленнее, чем использование функций Prelude.Я пытаюсь выяснить, если я делаю это неправильно, или если это ожидается.

Я провел профилирование и синхронизацию, используя (putStrLn.show) и ByteString эквиваленты тремя различными способами:

  1. Я проверяю каждого кандидата на предмет его простоты.Если это так, я добавляю его в список и записываю его с помощью (putStrLn. Show)
  2. . Я составляю список всех простых чисел и выписываю список с использованием (putStrLn. Unlines. Show)

Я ожидал, что числа 2 и 3 будут работать медленнее, так как вы строите список в одной функции и используете егов другой.Распечатывая числа по мере их генерации, я избегаю выделения памяти для списка.С другой стороны, вы делаете системный вызов call с каждым вызовом putStrLn.Правильно?Итак, я проверил, и # 1 на самом деле был самым быстрым.

Наилучшая производительность была достигнута с опцией № 1 и функциями Prelude ([Char]).Я ожидал, что моя лучшая производительность будет вариант № 1 с ByteString, но это не так.Я использовал только ленивые ByteStrings, но я не думал, что это будет иметь значение.Будет ли это?

Некоторые вопросы:

  • Вы ожидаете, что ByteStrings будут работать лучше для записи набора целых чисел в стандартный вывод?
  • Я пропустил шаблон путигенерировать и записывать ответы, которые приведут к повышению производительности?
  • Если я пишу только числа в виде текста, когда, если вообще, есть ли преимущество в использовании ByteString?

Моя рабочая гипотеза состоит в том, что написание Integer с помощью ByteString медленнее, если вы не объединяете их с другим текстом.Если вы объединяете Integer с [Char], то вы получите лучшую производительность, работая с ByteStrings.То есть перезапись ByteString:

putStrLn $ "the answer is: " ++ (show value)

будет намного быстрее, чем версия, написанная выше.Это правда?

Спасибо за чтение!

Ответы [ 2 ]

21 голосов
/ 12 мая 2011

Объем ввод обычно быстрее с байтовыми строками, так как данные плотные, просто меньше данных, которые можно перетаскивать с диска в память.

Запись данных как вывод однако, немного отличается.Как правило, вы сериализуете структуру, генерируете много небольших записей.Таким образом, плотные массовые записи байтовых строк в этом случае не сильно вам помогут.Даже обычный Strings будет работать разумно при инкрементальном выходе.

Однако не все потеряно.Мы можем восстановить быстрые массовые записи, эффективно создавая байтовые строки в памяти.Этот подход используется различными *-builder пакетами:

Вместо того, чтобы преобразовывать значения во множество крошечных байтовых строк и записывать их по одной за раз, мы транслируем преобразование в постоянно растущий буфер и, в свою очередь, записываем этот буфер в один большой фрагмент.Это приводит к гораздо меньшим издержкам ввода-вывода и повышению производительности (часто значительному) по сравнению со строковым вводом-выводом.

Такой подход используется, например, веб-серверами в Haskell или эффективной системой HTML, blaze .

Кроме того, производительность, даже при массовых записях, будет зависеть от эффективности любой функции преобразования между типами и строками байтов.Для Integer вы можете просто скопировать битовую комбинацию в памяти для вывода или вместо этого пройти через неэффективный декодер.В результате вам иногда приходится задумываться о качестве используемой функции кодирования, а не только о том, следует ли использовать Char / String или метод ввода-вывода.

7 голосов
/ 12 мая 2011

Обратите внимание, что производительность не является основным различием между ByteString и String.Первый предназначен для двоичных данных, а второй - для текста Unicode.Если у вас есть двоичные данные, используйте ByteString, если у вас есть текст Unicode, используйте тип Text из текстового пакета .

...