Сохранение попытки на диск

Это звучит как простой вопрос, но я не знаю, как найти на него ответ.

У меня есть реализация trie на С#, которая будет хранить около 80 тысяч слов из файла словаря. Загрузка всех этих слов занимает довольно много времени (более 5 минут). Мне было интересно, как лучше всего «сохранить» эти данные, чтобы мне не приходилось перезагружать все слова каждый раз, когда я запускаю приложение?

Спасибо.


person Dervin Thunk    schedule 20.09.2010    source источник
comment
Поскольку у нас нет кода, мы рассчитываем на то, что вы профилируете его, по крайней мере, достаточно подробно, чтобы определить, где находится узкое место.   -  person Steven Sudit    schedule 20.09.2010
comment
Почему вы хотите загрузить все 80 000 слов/узлов при запуске. Я считаю, что все эти слова классифицированы (/родительские узлы). расширить базовое дерево, чтобы загружать слова по требованию (событие щелчка/расширения родительского узла). Таким образом, вы будете загружать сначала группы, а затем узлы группы. Попробуйте использовать асинхронные вызовы для загрузки.   -  person Albert Arul prakash    schedule 20.09.2010
comment
Мне очень трудно поверить, что для заполнения дерева, содержащего всего 80 000 слов, требуется пять минут. Моя реализация вставляет от 0 до 999999 примерно за 60 мс. В этом случае я бы просто сохранил исходный список слов и воссоздал его по запросу.   -  person Rafe    schedule 20.09.2010
comment
Ваш алгоритм попытки кажется мне сломанным. За 5 минут вы можете выполнить 80k^2 ~= 6,4G строковых операций без особых проблем, что говорит мне о том, что ваш trie работает как связанный список.   -  person Rex Kerr    schedule 20.09.2010
comment
проблема не в выполнении операций над алгоритмами, а в том, что на самом деле проблема заключается в построении trie с 80K слов из какого-то txt-файла, где каждое слово находится в одной строке.   -  person Dervin Thunk    schedule 20.09.2010
comment
Сколько времени занимает чтение 80 КБ с диска или базы данных? И сколько времени нужно, чтобы фактически построить древовидное дерево? Мой ответ ниже сработал для меня в первую очередь потому, что построение дерева занимает слишком много времени.   -  person Kirk Broadhurst    schedule 21.09.2010


Ответы (3)


Как и все другие проблемы с производительностью, идеальное решение будет получено из профилирования вашего текущего решения и других возможных решений, которые вы придумаете. Где узкое место? Ввод/вывод? Лексировать текст? Формирование ссылок в дереве? Будет трудно сделать конкретное предложение, не зная ваших целей по производительности, характера использования trie и существующих узких мест.

Вопросы для рассмотрения:

  1. Формат хранения: Текст? Бинарный?
  2. Сохраняемые данные: вся структура дерева (например, в виде XML) или просто список слов, полагающийся на код времени выполнения, чтобы поместить их в нужное место в структуре данных? Каково соотношение разметки и данных? Насколько тяжело разбирать?
  3. Место хранения: БД/плоский файл/...?
  4. Инкрементная загрузка: возможна?

Одна из возможных стратегий: создать и поддерживать словарь «самых распространенных слов» с 1000 (или около того) наиболее часто используемых слов. Загружайте эти слова в trie при запуске и инициируйте загрузку полного словаря в другом потоке; постепенно добавляя к созданному дереву по мере чтения новых слов.

  • Плюсы: пользователь увидит более быстрое время запуска.
  • Минусы: может потребоваться синхронизация между потоками, пользователь увидит незавершенную попытку, пока загрузка не будет полностью завершена. Это может или не может быть шоу-стоппером в зависимости от того, для чего используется тройка.
person Ani    schedule 20.09.2010

Недавно я рефакторил аналогичную структуру данных из-за низкой производительности и медленной сериализации/десериализации.

Мое решение состояло в том, чтобы полностью отказаться от этой попытки и перейти к собственным коллекциям .NET - словарям и поискам.

Я работаю примерно с 400 тыс. слов. Из памяти требуется около 5 секунд, чтобы построить структуру данных, которая представляет собой список объектов, проиндексированных рядом словарей и поисковых запросов.

  • Верхний уровень структуры — это Dictionary<int, var>, где ключом является n — количество букв в поисковом запросе.
  • Каждое значение в словаре — это Lookup<string, string>, где ключ — это строка из n букв, а значение — это все строки, начинающиеся с этой строки. например, для ключа «st» значения могут быть «начало», «стоп» и «строка».

Чтобы создать структуру данных, я просто перебираю весь список слов от i = 1 до maxlength, чтобы создать поиск всех отдельных строк «начинается с» для каждого i. Вставьте их в словарь верхнего уровня, и все готово.

Это устраняет необходимость в пользовательском построении trie. Я обнаружил, что разница в производительности (время поиска) незначительна, но скорость загрузки чрезвычайно благоприятствует моему дизайну (не говоря уже о простоте и удобстве использования простых типов .NET).

person Kirk Broadhurst    schedule 20.09.2010
comment
Я понимаю, что на самом деле это не отвечает на ваш вопрос о том, как сериализовать, но я настоятельно рекомендую вам пересмотреть пользовательское дерево. На реализацию этого решения уходит менее часа, и, по моему опыту, оно гораздо более производительно. - person Kirk Broadhurst; 20.09.2010

Я бы просто сериализовал его в старом бинарном стиле MFC. По сути, чтение/запись должны быть максимально быстрыми, и единственное, что вам остается, это выделение и инициализация структуры на входе, что вам все равно нужно сделать.

То есть, чтобы сериализовать узел дерева, вы делаете следующее:

Read/Write number N of subnodes
For each subnode
  If reading, allocate a subnode in this node
  Read/Write the character for the subnode
  Serialize the subnode
End

Редактировать: просто перечитайте свой вопрос, и вы хотите построить тройку с нуля из списка слов? Как говорили другие, профилируйте, но не только с помощью любого старого профилировщика. Они не все находят вашу проблему. Вот что я делаю. Время, необходимое для этого, не должно быть намного больше, чем время, необходимое для чтения файла, плюс время, необходимое для создания структуры.

person Mike Dunlavey    schedule 20.09.2010