Каковы ключевые различия между Finger Tree (Data.Sequence) и канатом (Data.Rope) (версия Эдварда Кемта или версия Пьера-Этьена Менье >
В библиотеках Haskell Data.Sequence имеет больше функций. Я думаю, что веревки обрабатывают "блоки" более эффективно.
Как программист оценил эффективность, скажем, последовательность из 7 миллионов символов, где мне нужно (а) вставить где угодно, (б) вырезать и вставлять сегменты (сращивание), (в) искать и заменять подстроки, что более эффективно?
Разъяснения в ответ на ehird:
-
Основная часть моего алгоритма запускает тысячи операций поиска и замены, например
s/(ome)?reg[3]x/blah$1/g
, для многократного изменения данных. Поэтому мне нужно эффективное сопоставление шаблонов регулярных выражений (возможно, regex-tdfa?) , а также сплайсинг (данные [a: b] = newData), где необязательно(length(newData) == b-a+1)
-
Lazy ByteStrings может быть в порядке, но как насчет сращивания? Скрещивание ByteString - это линейное время O (dataSize/chunkSize) линейного времени (для поиска) плюс (возможно?) Накладные расходы для обслуживания блоков постоянного размера. (Может быть, неверно в отношении последней части); vs O (log (dataSize)) для FingerTree.
-
Мой тип данных "сдерживаемый" абстрактно представляет собой конечный алфавит. Он может быть представлен конкретно
Char
илиByte
илиWord8
или даже что-то вроде гипотетическогоWord4
(nibble). ** У меня есть связанный вопрос о том, как эффективно использоватьnewtype
илиdata
, чтобы мой код мог ссылаться на абстрактный алфавит, но скомпилированная программа все еще может быть эффективной. (Я должен опубликовать этот вопрос отдельно.) -
Проблемы с производительностью. Возможно, Seq намного хуже, чем ByteString (по q значимому постоянному коэффициенту). В простых тестах, прочитав 7 МБ в строгом
ByteString
, а затем распечатав его на консольные пики при использовании реальной памяти 60 МБ (в соответствии с Windows Process Manager), но загружая это содержимое вSeq Char
, а затем печать использует 400 МБ! (Я должен опубликовать этот вопрос отдельно, с информацией о кодах и профилировании.) -
Проблемы с платформой. Я использую EclipseFP и платформу Haskell. У меня есть текст, установленный на моей машине, и я хотел попробовать, но моя среда Eclipse не может его найти. У меня возникают серьезные проблемы, когда я использую
cabal install
(несовместимые версии пакетов устанавливаются, путаница--user
vs--global
), поэтому я хочу придерживаться пакетов Platform, которые может найти EclipseFP. Я думаю, что Text переходит в следующую версию Platform, так что это будет хорошо. -
Trifectastrong > . Я кратко увидел Trifecta, и это просто добавило мне в замешательство. (Почему у него есть собственные новые реализации общих структур данных, которые уже опубликованы? Они лучше? Слишком много почти идентичных опций!)
Отредактировано с более подробной информацией и улучшенными ссылками.
Этот вопрос стал большим.
Сводка @ehird является основной точкой приема. Веревку или дерево пальцев байтов или векторов плюс небольшой пользовательский моноид. В любом случае, мне нужно будет написать простую реализацию регулярного выражения, чтобы приклеить.
Учитывая всю эту информацию, я бы рекомендовал либо Веревку, либо здание ваша собственная структура с пакетом fingertree, на котором она основана (скорее чем Seq, чтобы вы могли правильно выполнять такие вещи, как длина Тип измеряемого типа - см. Моноиды и пальмовые деревья), с листом данные, помеченные в unboxed Vector. Последнее, конечно, больше работа, но позволяет вам оптимизировать специально для вашего прецедента. Так или иначе, определенно завершите его в абстрактном интерфейсе.
Я вернусь позже сегодня и разделился на новые вопросы. Я получу низкоуровневые технические вопросы, а затем вернусь к общему сравнению. Я изменю заголовок вопроса, чтобы лучше отразить мою реальную проблему. "Какие модули Haskell предоставляют или поддерживают операции манипуляции последовательностями, которые мне нужны эффективно?" Благодарим вас за чужие и другие ответчики.