Массивы Haskell против списков

Я играю с Haskell и Project Euler 23-й проблемой. После решения этого списка я пошел здесь, где я увидел, что некоторые массивы работают. Это решение было намного быстрее, чем мое. Так вот вопрос. Когда следует использовать массивы в Haskell? Является ли их производительность лучше, чем списки? И в каких случаях?

Ответ 1

И если вы делаете много индексирования, а также много обновлений, вы можете

  • использовать Map (или IntMap s), индексирование и обновление O (размер журнала), достаточно хорошее для большинства целей, код легко получить право
  • или, если Map слишком медленны, используйте изменяемые (распакованные) массивы (STUArray из Data.Array.ST или STVectors из пакета vector; O (1) индексирование и обновление, но код легче ошибиться и вообще не так хорош.

Для конкретных целей такие функции, как accumArray, также дают очень хорошую производительность (с помощью изменяемых массивов под капотом).

Ответ 2

Наиболее очевидное различие такое же, как и в других языках: массивы имеют O (1) поиск и списки имеют O (n). Прикрепление чего-либо к заголовку списка (:) принимает O (1); добавление (++) принимает O (n).

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

Модификация неизменяемых массивов сложна - вам нужно скопировать весь массив, который принимает O (n). Если вы используете изменяемые массивы, вы можете изменить их в O (1) раз, но вам придется отказаться от преимуществ иметь чисто функциональное решение.

Наконец, списки намного проще работать, если производительность не имеет значения. Для небольших объемов данных я всегда использовал список.

Ответ 3

Массивы имеют O (1) индексацию (это было частью определения Haskell), тогда как списки имеют O (n) индексацию. С другой стороны, любая модификация массивов - это O (n), поскольку она должна копировать массив. Поэтому, если вы собираетесь делать много индексирования, но мало обновляете, используйте массивы.