Есть ли любой сценарий, где структура данных Веревки более эффективна, чем строковый разработчик

Загрузите источник Ruby 1.9 и выпуск make golf, тогда можно сделать вещи как это:

make golf

./goruby -e 'h'
# => Hello, world!

./goruby -e 'p St'
# => StandardError

./goruby -e 'p 1.tf'
# => 1.0

./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/ruby-svn/src/trunk"

Read golf_prelude.c для большего количества аккуратных вещей, скрывающихся.

24
задан Community 23 May 2017 в 12:34
поделиться

4 ответа

В документации для реализации SGI C ++ подробно описывается большая буква O поведение против постоянных факторов, что поучительно.

Их документация предполагает, что задействованы очень длинные строки , примеры, приведенные для справки, говорят о строках размером 10 МБ . Будет написано очень мало программ, которые имеют дело с такими вещами, и для многих классов проблем с такими требованиями их переработка, чтобы они основывались на потоках , вместо того, чтобы требовать, чтобы полная строка была доступна, где это возможно, приведет к значительно лучшим результатам. .

  • Обратите внимание, что строки .Net, в отличие от строк java, не разделяют символьный буфер на подстроки - выбор с плюсами и минусами с точки зрения объема памяти. Веревки, как правило, позволяют избежать подобных проблем.
  • Веревки позволяют отложить загрузку подстрок до тех пор, пока они не потребуются.
    • Обратите внимание, что это сложно сделать правильно, очень легко сделать бессмысленным из-за чрезмерного желания доступа и требует использования кода, чтобы рассматривать его как веревку, а не как последовательность символов.
  • Существенные минусы:

    • Произвольный доступ для чтения становится O (log n)
    • Постоянные коэффициенты при последовательном доступе для чтения, кажется, находятся между 5 и 10
    • эффективное использование API требует обращения с ним как с веревкой, а не просто с опусканием в веревке в качестве вспомогательной реализации на «нормальном» строковом API.

    Это приводит к нескольким «очевидным» применениям (первое явно упоминается SGI).

    • Буферы редактирования для больших файлов, позволяющие легко отменить / повторить
      • Обратите внимание, что в какой-то момент вам может потребоваться записать изменения на диск, включая потоковую передачу по всей строке, поэтому это полезно только в том случае, если большинство изменений будет в основном находиться в памяти, а не требовать частого сохранения (например, через функцию автосохранения )
    • Манипуляции с сегментами ДНК, где происходят значительные манипуляции, но на самом деле происходит очень мало результатов.
    • Многопоточные алгоритмы, которые изменяют локальные части строки. Теоретически такие случаи можно разделить на отдельные потоки и ядра без необходимости брать локальные копии подсекций и затем рекомбинировать их, что экономит значительную часть памяти, а также позволяет избежать дорогостоящей операции последовательного объединения в конце.

    Бывают случаи, когда поведение строки, зависящее от предметной области, может быть связано с относительно простыми дополнениями к реализации Rope, чтобы:

    • Строки только для чтения со значительным количеством общих подстрок поддаются простому интернированию для значительной экономии памяти.
    • Строки с разреженными структурами или значительным локальным повторением поддаются кодированию длины прогона, при этом обеспечивая разумные уровни произвольного доступа.
    • 1230] Где границы подстроки сами являются «узлами», где может храниться информация, хотя такие структуры вполне возможно лучше сделать как Radix Trie , если они редко изменяются, но часто читаются.

    Как вы Как видно из приведенных примеров, все они хорошо попадают в категорию «нишевых». Кроме того, некоторые из них могут иметь лучшие альтернативы, если вы желаете / можете вместо этого переписать алгоритм как операцию обработки потока.

  • Строки с разреженными структурами или значительным локальным повторением поддаются кодированию длины прогона, при этом позволяя разумные уровни произвольного доступа.
  • Если границы подстроки сами являются «узлами», в которых может храниться информация, хотя такие структуры являются вполне возможно, лучше использовать как Radix Trie , если они редко изменяются, но часто читаются.
  • Как вы можете видеть из перечисленных примеров, все они хорошо попадают в категорию «нишевых». Кроме того, некоторые из них могут иметь превосходные альтернативы, если вы желаете / можете вместо этого переписать алгоритм как операцию обработки потока.

  • Строки с разреженными структурами или значительным локальным повторением поддаются кодированию длин серий, при этом позволяя разумные уровни произвольного доступа.
  • Если границы подстроки сами являются «узлами», где может храниться информация, хотя такие структуры являются вполне возможно, лучше сделать как Radix Trie , если они редко изменяются, но часто читаются.
  • Как вы можете видеть из перечисленных примеров, все они хорошо попадают в категорию «нишевых». Кроме того, некоторые из них могут иметь лучшие альтернативы, если вы желаете / можете вместо этого переписать алгоритм как операцию обработки потока.

    где может храниться информация, хотя такие структуры вполне возможно лучше сделать в виде Radix Trie , если они редко изменяются, но часто читаются.

    Как вы можете видеть из перечисленных примеров, все они хорошо вписываются в структуру «нишевая» категория. Кроме того, некоторые из них могут иметь лучшие альтернативы, если вы желаете / можете вместо этого переписать алгоритм как операцию обработки потока.

    где может храниться информация, хотя такие структуры вполне возможно лучше сделать в виде Radix Trie , если они редко изменяются, но часто читаются.

    Как вы можете видеть из перечисленных примеров, все они хорошо вписываются в структуру «нишевая» категория. Кроме того, некоторые из них могут иметь превосходные альтернативы, если вы желаете / можете вместо этого переписать алгоритм как операцию обработки потока.

    27
    ответ дан 28 November 2019 в 23:10
    поделиться

    краткий ответ на этот вопрос - да, и это требует небольшого объяснения. Конечно, есть ситуации, когда структура данных Rope более эффективна, чем построитель строк. они работают по-разному, поэтому больше подходят для разных целей.

    (С точки зрения C #)

    Структура данных веревки в виде двоичного дерева лучше в определенных ситуациях. Когда вы смотрите на чрезвычайно большие строковые значения (представьте, что 100+ МБ xml, поступающего из SQL), структура данных веревки может удерживать весь процесс за пределами кучи больших объектов, где строковый объект попадает в него, когда он передает 85000 байт.

    Если вы смотрите на строки из 5–1000 символов, вероятно, это не улучшит производительность настолько, чтобы того стоило.

    12
    ответ дан 28 November 2019 в 23:10
    поделиться

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

    Rope отлично подходит, если есть много префиксов (очевидно, слово «добавление» придумано ИТ-специалистами и не является подходящим словом!) И потенциально лучше для прошивок; StringBuilder использует непрерывную память, поэтому эффективно работает только для добавления.

    Следовательно, StringBuilder отлично подходит для создания строк путем добавления фрагментов - очень нормальный вариант использования. Поскольку разработчикам приходится делать это очень часто, StringBuilders - очень распространенная технология.

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

    Вам нужны действительно большие объемы данных и отток, чтобы заставить окупаемость веревки - процессоры очень хороши в потоковых операциях, и если у вас есть оперативная память, тогда просто перераспределение для префикса действительно работает приемлемо для обычных случаев использования. Это соревнование, упомянутое вверху, было единственным разом, когда я видел, что он нужен. и если у вас есть ОЗУ, тогда просто перераспределение префикса работает приемлемо для обычных случаев использования. Это соревнование, упомянутое вверху, было единственным разом, когда я видел, что он нужен.

    и если у вас есть ОЗУ, тогда просто перераспределение для префикса работает приемлемо для обычных сценариев использования. Это соревнование, упомянутое вверху, было единственным разом, когда я видел, что он нужен.

    11
    ответ дан 28 November 2019 в 23:10
    поделиться

    Большинство продвинутых текстовых редакторов представляют тело текста как «своего рода веревку» (хотя в реализации листья обычно не отдельные символы, а бегущие строки), главным образом для улучшения частых вставок и удаляет большие тексты.

    Обычно StringBuilder оптимизирован для добавления и пытается минимизировать общее количество перераспределений без чрезмерного превышения доступности. Типичная гарантия составляет (log2 N выделений и меньше 2,5-кратного объема памяти). Обычно строка создается один раз, а затем может использоваться в течение некоторого времени без изменения.

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

    1
    ответ дан 28 November 2019 в 23:10
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: