2012-01-17 4 views
1

Я ищу реализацию trie для .net.Эффективная реализация trie для .net

Я планирую использовать его в качестве структуры индекса для моего пула объектов в памяти. Он не должен быть потокобезопасным (поскольку только один поток будет его обновлять), но он должен иметь возможность не менее 20 миллионов элементов изящно и с постоянной производительностью.

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

PS: Я выбрал попытки, поскольку, похоже, реализация хэш-таблиц, которые я видел, использует слишком много памяти и, как правило, вызывает фрагментацию памяти, поскольку они основаны на массивах. Любой такой контейнер с характеристиками поиска O (1) и полезными характеристиками памяти для большого количества элементов также может быть в порядке.

Спасибо,

+0

20 миллионов элементов? Использование памяти в trie в этом случае почти гарантированно будет больше, чем словарь/хэш-таблица - возможно, на несколько порядков ... Также вам действительно нужен пул объектов в памяти? Собственное управление памятью .Net довольно прочное. –

+0

Какие стандартные структуры данных вы пробовали и соответствовали вашим потребностям? (объясните, почему) – Peter

ответ

0

По моему личному мнению, пытающегося предугадывать собственное управление памятью .NET не является практикой я рекомендую. Вы просто не можете обеспечить уровень управления распределением памяти, который вы можете в собственном сценарии, но в равной степени вам не нужно. Я был одержим желанием сделать это, когда я впервые перешел с C++ (где я регулярно работал со своими собственными кучами и записывал процедуры локализации памяти и т. Д.), Но быстро стало очевидно, что мне просто не нужно, или может I.

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

Это означает, что вместо этого используется тип значения, но они просто не подходят для использования в объединенном сценарии, потому что пользовательские типы значений должны быть неизменными (я могу сказать, что безопасно, не оправдывая его - просто google 'неизменяемый' и ' struct 'targetpage site: stackoverflow.com, чтобы увидеть больше), и поэтому не следует относиться к объектам многократного использования.

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

Если у вас слишком много объектов, чтобы поместиться в памяти, то либо:

1) Получить больше памяти

2) использовать базу данных и кэш локальных сегментов ней

Или как: Вы могли бы рассмотрите вопрос о AppFabric and its cache features, таким образом вы можете построить ферму машин, предназначенную для работы в кэшах в памяти миллионов объектов. Стоимость аппаратных средств, вероятно, будет меньше, чем стоимость разработки собственного решения для управления памятью для .Net :)

+0

Я фактически пробовал все реализации хэш-таблицы в .net-среде, а также C5-библиотеку.Проблема с хэш-таблицами заключается в том, что они основаны на массивах. Как только их буферы массивов заполняются, они пытаются перераспределить всю структуру с двойной емкостью. Поэтому, если в системе много добавлений, это приводит к фрагментации памяти и ошибкам памяти, поскольку смежные ячейки памяти быстро истощаются. Реализация хеш-таблицы, которая не работает, будет очень полезна, но не может найти ее. –

+0

Массив ссылок примерно такой же размер, как размер массива указателей. В вашем случае 20 mill = около 80Mb или 160Mb в 64-битной земле. Почему бы просто не создать хэш-таблицу или словарь с большой начальной емкостью? –

+0

Спасибо, Золтан, и извините за поздний ответ. Должно быть, я пропустил, что не ответил на ваши предложения. Это действительно то, как я закончил делать, то есть предварительно распределить большой кусок, близкий к моему окончательному размеру, и позволить ему играть с использованием стандартного словаря. Я также играл с сокращением словарного ключа до меньших частей и сохранением иерархии словарей. Это также работает, но отслеживание суб-суб-словарей является сложным и не дает большого преимущества, если я знаю цифру максимального размера. Итак, я пошел с простым подходом в конце. –

-1

Взгляните на эту библиотеку: TrieNet

using Gma.DataStructures.StringSearch; 

... 

var trie = new SuffixTrie<int>(3); 

trie.Add("hello", 1); 
trie.Add("world", 2); 
trie.Add("hell", 3); 

var result = trie.Retrieve("hel"); 
+0

Пожалуйста, не просто отправляйте какой-либо инструмент или библиотеку в качестве ответа. По крайней мере, продемонстрируйте [как он решает проблему] (http://meta.stackoverflow.com/a/251605) в самом ответе. – paper1111

+0

1. Это точно ожидаемый ответ на вопрос. Так почему бы не? 2. Я являюсь автором этой широко используемой библиотеки, и в репозитории имеется достаточно примеров и документации. –

+1

См. Https://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers/8259#8259. Вы должны включить пример в ответ. – paper1111