Высокоэффективный map<some_string_type,some_datum>
От: cranky Украина  
Дата: 02.09.05 17:56
Оценка: 65 (3) -1
В последнее время на РСДН участились обсуждения отображений с ключами-строками:
Re[19]: Про итераторы
Автор: jedi
Дата: 27.08.05

Быстрое сравнение строк
Автор: Fahrain
Дата: 27.07.05

и другие...

В большинстве реализаций STL существуют два подхода для организации отображений: map и hash_map. Ни тот, ни другой не являются эффективными для не-скалярных типов, таких как массивы, строки и т.п.
map использует red-black-tree со сравнением целых строк в каждом узле.
hash_map считает для целой строки хеш-код, затем сравнивает строки целиком, причём кол-во таких сравнений равно кол-ву строк с совпадающим хеш-кодом. Дополнительный недостаток — значения при добавлении не сортируются по ключам.
Но есть и третий подход — использование деревьев цифрового поиска (trie). Такая структура данных позволяет находить нужный узел на основании внутреннего представления строки, сравнивая строки лишь один раз. Наиболее эффективной из таких структур является PATRICIA trie, изобретенная в 1968 Дональдом Р. Моррисоном специально для быстрого поиска в больших объемах текстовой информации. Возможности такого дерева весьма высоки, краткое описание алгоритма добавления/поиска в нем можно увидеть, например, в 3-ем томе "Искусства программирования" Кнута.

Исходя из всего этого, у меня возникла идея создать шаблон контейнера pat_map, который бы в обобщённом виде реализовал структуру PATRICIA trie, и был бы однообразным и совместимым с другими контейнерами и алгоритмами STL.
Заголовочный файл с шаблоном и пример использования (concordance). (компилируется MSVC 6, Intel C++ 6, MSVC 7.1)
Для тестирования производительности собрал два эквивалентных релиза (MSVC 7.1 with max optimization): этот
Автор: jedi
Дата: 27.08.05
(с использованием std::map) и свой (using pat_map).
Времена подсчёта словоупотреблений для файла 72М (очищенные русские тексты, слова в нижнем регистре и пробел) на P4-2.8 1G RAM:
Результаты вычислений совпадают. Максимум использования RAM для обеих программ был одинаков и составил 20М.
Как видно, производительность в случае использования правильной структуры данных повысилась на 25%.
Вообще говоря, это ещё не окончательная версия (в которой планируются pat_set + удаление узлов + некоторые оптимизации + полная возможная совместимость с STL), но даже в таком виде шаблон pat_map будет полезен.

PS Пожелания и предложения принимаются с благодарностью
You aren't expected to absorb this
Re: Высокоэффективный map<some_string_type,some_datum>
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.09.05 22:40
Оценка:
Здравствуйте, cranky, Вы писали:

Теперь возми хорошую реализацию хэш-таблицы и хэшфункции и убедись, что потратил время зря.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Высокоэффективный map<some_string_type,some_datum>
От: cranky Украина  
Дата: 04.09.05 11:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, cranky, Вы писали:


VD>Теперь возми хорошую реализацию хэш-таблицы и хэшфункции и убедись, что потратил время зря.


Взял std::hash_map из MSVC 7.1 и хеш-функцию:
class string_hash_compare
    : public hash_compare<string>
{
public:
    size_t operator()(const string &key) const
    {
        size_t h=0;
        for (string::const_iterator it=key.begin();it!=key.end();++it)
            h=5*h+*it;
        return h;
    }
    bool operator()(const string &key1,const string &key2) const
    {
        return comp(key1,key2);
    }
};

Достаточно хороши?
Получил на том же тексте 24.1 сек. и хорошо перемешанный список слов с их частотой. Или может есть хеш-функция, позволяющая хранить записи, сортированные по ключу?
На всякий случай напомню: это ещё только зачаточная версия контейнера. В нём планируются такие возможности, которые хешированию так же недоступны, как и хранение в отсортированном виде. В частности, PATRICIA trie позволяет использовать в качестве ключей бесконечные строки. Это может быть полезно для нахождения всех позиций в большом файле, где начинается искомая строка.
You aren't expected to absorb this
Re[3]: Высокоэффективный map<some_string_type,some_datum>
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.09.05 15:41
Оценка:
Здравствуйте, cranky, Вы писали:

C>Достаточно хороши?

C>Получил на том же тексте 24.1 сек.

Я бы назвал эту реализацию посредственной. Но как видишь она уже показала себя лучше дерева.

C> и хорошо перемешанный список слов с их частотой. Или может есть хеш-функция, позволяющая хранить записи, сортированные по ключу?


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

C>На всякий случай напомню: это ещё только зачаточная версия контейнера. В нём планируются такие возможности, которые хешированию так же недоступны, как и хранение в отсортированном виде. В частности, PATRICIA trie позволяет использовать в качестве ключей бесконечные строки. Это может быть полезно для нахождения всех позиций в большом файле, где начинается искомая строка.


Я не спорю, что твой контейнер имеет право на существование и хорош в некоторых случаях. Я не согласен с твоим утверждением:

В большинстве реализаций STL существуют два подхода для организации отображений: map и hash_map. Ни тот, ни другой не являются эффективными для не-скалярных типов, таких как массивы, строки и т.п.

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

Нумаю ты понимашь, что чем сложнее тип используемый в качестве ключа, тем эффективнее может быть хэш-таблица? Ведь хэш-значение можно вычислить один раз и закэшировать в кэземпляре. Далее поиск слота осуществляется практически в костантное время и при минимуме вычислений. А сравнение ведется на очень малом объеме списка. В итоге чем больше объем данных — тем фээективнее хэш-таблица. Для защиты от коллизий можно вместо списка коллизий хранить деревья или отсортированные массивы значений. В общем, алгоритмически у чистых деревьев просто нет шансов. Смысл в них есть только если нужна постоянная отсортированность. Что является довольно большой редкостью.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Высокоэффективный map<some_string_type,some_datum>
От: cranky Украина  
Дата: 04.09.05 17:54
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я не спорю, что твой контейнер имеет право на существование и хорош в некоторых случаях. Я не согласен с твоим утверждением:

VD>

В большинстве реализаций STL существуют два подхода для организации отображений: map и hash_map. Ни тот, ни другой не являются эффективными для не-скалярных типов, таких как массивы, строки и т.п.

VD>Сам по себе hash_map — это классическая таблица. То что он не важно реализован в некоторых версиях STL еще ни о чем не говорит. К тому же hash_map не входит в стандарт и является частным расширением. Ну, а его опрадванность ты мог наблюдать сам.

Оки, я согласен, что hash_map я зацепил по инерции, но тогда он просто не из той оперы, ибо добивается несколько иных целей и делает это, естественно, по-другому. Хотя... Дело в том, что положение узла в trie определяется исходя из значений битов, указывающих, в какую сторону поворачивать. Но никто не ограничивает, в каком порядке эти биты располагаются в ключе, и есть ли они там вообще. Следовательно, возможно придумать такой порядок вычисления битов, который будет эквивалентен значению хеш-функции от этого ключа. Получается, что на деревьях можно эмулировать работу сколь угодно сложной хеш-таблицы, естественно также без гарантии сортированности по ключу. Тем более в моей реализации выдача значений битов ключа вынесена в отдельный класс.

VD>Нумаю ты понимашь, что чем сложнее тип используемый в качестве ключа, тем эффективнее может быть хэш-таблица? Ведь хэш-значение можно вычислить один раз и закэшировать в кэземпляре. Далее поиск слота осуществляется практически в костантное время и при минимуме вычислений.


Аналогично и с порядком выборки битов: если его сложно вычислять — он кешируется.

VD>А сравнение ведется на очень малом объеме списка. В итоге чем больше объем данных — тем фээективнее хэш-таблица. Для защиты от коллизий можно вместо списка коллизий хранить деревья или отсортированные массивы значений. В общем, алгоритмически у чистых деревьев просто нет шансов.


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

VD>Смысл в них есть только если нужна постоянная отсортированность. Что является довольно большой редкостью.


Отсортированность — необязательное условие для деревьев цифрового поиска. Ею при необходимости можно пожертвовать.
You aren't expected to absorb this
Re[5]: Высокоэффективный map<some_string_type,some_datum>
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.09.05 21:04
Оценка:
Здравствуйте, cranky, Вы писали:

C>Оки, я согласен, что hash_map я зацепил по инерции, но тогда он просто не из той оперы, ибо добивается несколько иных целей и делает это, естественно, по-другому.


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

C> Хотя... Дело в том, что положение узла в trie определяется исходя из значений битов, указывающих, в какую сторону поворачивать. Но никто не ограничивает, в каком порядке эти биты располагаются в ключе, и есть ли они там вообще. Следовательно, возможно придумать такой порядок вычисления битов, который будет эквивалентен значению хеш-функции от этого ключа. Получается, что на деревьях можно эмулировать работу сколь угодно сложной хеш-таблицы, естественно также без гарантии сортированности по ключу. Тем более в моей реализации выдача значений битов ключа вынесена в отдельный класс.


Что то я тебя не пойму. Причем тут биты? Дериво и так польностью эмулирвет поведение хэш-таблицы. Только делает оно это на баже поддержания сортированности. А это, с одной стороны требует того чтобы элементы коллекции можно было сравнивать на болше/меньше, что не всегда удобно/допустимо (например, что больше Иванов или Сидоров?). А сдругой стороны — это банально более медненно. Ведь для поиска элементов в бинарном дереве поиска используется бинарный поиск (полвинным делением), а в хэш-таблице просто вычисляется хэш-функция и на ее основании вычисляется слот хэш-таблицы. Если коллезий нет, то скорость просто константная.

C>Аналогично и с порядком выборки битов: если его сложно вычислять — он кешируется.


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

C>Если смущает поиск по дереву — можно применить специальный вектор, содержащий указатели на вершины, соответствущие префиксу ключа заранее определённой длины. Тогда останется пройтись по дереву меньшего объёма — аналогия с деревом коллизий. Эта возможность тоже в планах.


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

C>Отсортированность — необязательное условие для деревьев цифрового поиска. Ею при необходимости можно пожертвовать.


Ох, ох, ох... Как же это не обязательное? Оно даже называется "Бинарное дерево поиска".
В общем, почитай вот эти вещи:
http://www.optim.ru/cs/2000/4/bintree_htm/beentree_main.asp
http://www.optim.ru/cs/2000/4/bintree_htm/hash.asp
А то у тебя какие-то странные представления. Или изложи свои идеи. Как же можно искать в неупорядоченных деревьях.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Высокоэффективный map<some_string_type,some_datum>
От: CreatorCray  
Дата: 04.09.05 22:49
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что то я тебя не пойму. Причем тут биты?

VD>О каких битах ты все время ведешь речь?
VD>А то у тебя какие-то странные представления. Или изложи свои идеи. Как же можно искать в неупорядоченных деревьях.
Почитай теорию по Patricia деревьям, а...
А то похоже ты принцип их работы совершенно не понимаешь. Patricia дерево выглядит примерно так

0
0
1
0
-A-
0 1
0 0
1 0
B C
0 1 0 1
0 E 1 0
1 1 G
0 F
D

A — G — ноды (цифры над ними по дереву до самого верха — соответствующие им ключи)
т.е. для ноды F ключ = 0010100011, для ноды D = 00100010010
Но при этом можно создать такое дерево

0
0
1
0
---A
0 1
0 0
1
_B
0 1
0 0

1 1
0
С

Тут уже A = 001010, B = 0010001101, C = 00100010010

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

Пример: ключ поиска = 0010001101
Нода А — совпало 0010. Бит разницы — 0, перехожу на левого чайлда и сравниваю дальше
Нода В — совпало 001. Бит разницы — 1, перехожу на правого чайлда и сравниваю дальше
Нода В — совпало 101. Больше чайлдов нет — нашел нужную ноду

Пример: ключ поиска = 00101101
Нода А — совпало 0010. Бит разницы — 1, перехожу на правого чайлда и сравниваю дальше
Нода А — совпало 1. До бита разницы не дошло — искомой ноды нет
Re[7]: Высокоэффективный map<some_string_type,some_datum>
От: cranky Украина  
Дата: 05.09.05 05:46
Оценка:
Здравствуйте, CreatorCray, Вы писали:

[...]

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


Стоит добавить только, что обычно "оптимизация" заключается в сохранении номера бита различия в ноде, что позволяет иметь всего один узел на ключ.

CC>В результате поиск элемента в таком дереве линейна и зависит от длинны ключа.


Скорее сложность поиска это сумма [O(ln N) + O(K)], где N — общее кол-во узлов в дереве, K — длина ключа.
You aren't expected to absorb this
Re[7]: Высокоэффективный map<some_string_type,some_datum>
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.09.05 20:01
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>В результате поиск элемента в таком дереве линейна и зависит от длинны ключа.


И зачем это нужно? Или ты не верно выразился, или это бесполезная трата времени.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Высокоэффективный map<some_string_type,some_datum>
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.09.05 20:01
Оценка:
Здравствуйте, cranky, Вы писали:

C>Скорее сложность поиска это сумма [O(ln N) + O(K)], где N — общее кол-во узлов в дереве, K — длина ключа.


Здорово. Скоростная характеристика хэш-тиблицы в отсуствии коллизий O(1) и не завист от размера ключа.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Высокоэффективный map<some_string_type,some_datum>
От: cranky Украина  
Дата: 06.09.05 04:19
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, cranky, Вы писали:


C>>Скорее сложность поиска это сумма [O(ln N) + O(K)], где N — общее кол-во узлов в дереве, K — длина ключа.


VD>Здорово. Скоростная характеристика хэш-тиблицы в отсуствии коллизий O(1) и не завист от размера ключа.


А сложность вычисления хорошего хеш-значения ключа тоже стала константной и не зависит от длины ключа?
You aren't expected to absorb this
Re[10]: Высокоэффективный map<some_string_type,some_datum>
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.09.05 19:53
Оценка:
Здравствуйте, cranky, Вы писали:

C>А сложность вычисления хорошего хеш-значения ключа тоже стала константной и не зависит от длины ключа?


Зависит от алгоритма. Может и не зависить. Но если бы ты читал внимательнее, то заметил бы, что хэш легко кешируется. Так что вычислять его каждый раз не нужно.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Высокоэффективный map<some_string_type,some_datum>
От: c-smile Канада http://terrainformatica.com
Дата: 07.09.05 06:37
Оценка:
Здравствуйте, cranky, Вы писали:

C>PS Пожелания и предложения принимаются с благодарностью


Угу, вот еще мое:
http://rsdn.ru/Forum/Message.aspx?mid=824201&amp;only=1
Автор: c-smile
Дата: 25.09.04

На больших наборах TST лучше плюс всякие вкусности типа "найти похожий".
Re[2]: Высокоэффективный map<some_string_type,some_datum>
От: kluxer Украина  
Дата: 07.09.05 09:58
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, cranky, Вы писали:


C>>PS Пожелания и предложения принимаются с благодарностью


CS>Угу, вот еще мое:

CS>http://rsdn.ru/Forum/Message.aspx?mid=824201&amp;only=1
Автор: c-smile
Дата: 25.09.04


Интересно, спасибо. Надо будет и себе такое сделать, думаю получится. Даже мнится, что перебор в partial_match будут делать итераторы, может даже стандартные

CS>На больших наборах TST лучше плюс всякие вкусности типа "найти похожий".


Хм, а если применить правильный аллокатор для узлов, возможно они и сравняются в производительности... Алгоритмы-то родственные, насколько я не напутал. Сложность одинакова. Вкусности и у моих шаблонов планируются, но потом
You aren't expected to absorb this
Оптимальная хеш-функция?
От: kluxer Украина  
Дата: 07.09.05 11:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, cranky, Вы писали:


C>>Достаточно хороши?

C>>Получил на том же тексте 24.1 сек.

VD>Я бы назвал эту реализацию посредственной. Но как видишь она уже показала себя лучше дерева.


Такой вопрос: какая хеш-функция будет оптимальной для реализации хеш-таблицы в STL VC 7.1?
Интересуюсь, потому что в "Компиляторах" приведена такая:
    size_t operator()(const string &key) const
    {
        size_t h=0,g;
        for (string::const_iterator it=key.begin();it!=key.end();++it)
        {
            if (g=(h=(h<<4)+*it)&0xF0000000)
                h^=g>>24^g;
        }
        return h;
    }

Называется hashpjw и в тестировании даёт "неплохие результаты для всех размеров таблиц". "Неплохие" в этой цитате — это наиболее быстрые? Но проведённые мною эксперименты с замером производительности дают странный результат — hash_map с hashpjw всегда немного отстаёт от моего мапа, в то время как "посредственная реализация" всегда несколько опережает его. Почему так получается и какая функция будет самой эффективной для моих данных (большое кол-во (300-500К) повторяющихся с разной частотой строк длиной 1..25 символов)?
You aren't expected to absorb this
Re: Оптимальная хеш-функция?
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.09.05 12:36
Оценка:
Здравствуйте, kluxer, Вы писали:

K>Такой вопрос: какая хеш-функция будет оптимальной для реализации хеш-таблицы в STL VC 7.1?


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

K>Интересуюсь, потому что в "Компиляторах" приведена такая:

K>
    size_t operator()(const string &key) const
K>    {
K>        size_t h=0,g;
K>        for (string::const_iterator it=key.begin();it!=key.end();++it)
K>        {
K>            if (g=(h=(h<<4)+*it)&0xF0000000)
K>                h^=g>>24^g;
K>        }
K>        return h;
K>    }
K>

K>Называется hashpjw и в тестировании даёт "неплохие результаты для всех размеров таблиц".

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

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

K> "Неплохие" в этой цитате — это наиболее быстрые? Но проведённые мною эксперименты с замером производительности дают странный результат — hash_map с hashpjw всегда немного отстаёт от моего мапа, в то время как "посредственная реализация" всегда несколько опережает его. Почему так получается и какая функция будет самой эффективной для моих данных (большое кол-во (300-500К) повторяющихся с разной частотой строк длиной 1..25 символов)?


Возможно вычисление хэш-функции оказывается на тестируемых объемах более затратным чем сам поиск. А возможно что функция на твоих данных дает много коллизий. Это легко определить опытным путем. Если проблема в скорости хэш-функции, то можно просто кэшировать результат. Если в качестве, то нужно ее выбрасывать.
... << RSDN@Home 1.2.0 alpha rev. 606>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Высокоэффективный map<some_string_type,some_datum>
От: kluxer Украина  
Дата: 07.09.05 17:10
Оценка:
C>Исходя из всего этого, у меня возникла идея создать шаблон контейнера pat_map, который бы в обобщённом виде реализовал структуру PATRICIA trie, и был бы однообразным и совместимым с другими контейнерами и алгоритмами STL.
C>Заголовочный файл с шаблоном и пример использования (concordance). (компилируется MSVC 6, Intel C++ 6, MSVC 7.1)

Версия 0.05 (компилируется MSVC 7.1)

Изменения к лучшему:

Отличия от set и map: некоторые различия в работе методов lower_bound и подобных. Обусловлены отсутствием предиката и присутствием бит-компаратора, а также возможностью бесконечного ключа. Но об этом в будущей документации.
You aren't expected to absorb this
Re[11]: Высокоэффективный map<some_string_type,some_datum>
От: CreatorCray  
Дата: 07.09.05 17:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, cranky, Вы писали:


C>>А сложность вычисления хорошего хеш-значения ключа тоже стала константной и не зависит от длины ключа?


VD>Зависит от алгоритма. Может и не зависить. Но если бы ты читал внимательнее, то заметил бы, что хэш легко кешируется. Так что вычислять его каждый раз не нужно.


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

Давайте этот спор решим просто: набросаем тестовую программку с выполнением пары-тройки приближенных к реальным задачам алгоритмов с применением hash_map и patricia trie (+можно еще и ternary tree до кучи)
И можно на практике посмотреть на эффективность.
Потому как к сырой теории у меня полного доверия нет. Сколько раз напарывался что в теории все гладко а на практике полное г.
Re[12]: Высокоэффективный map<some_string_type,some_datum>
От: CreatorCray  
Дата: 07.09.05 21:03
Оценка:
... дополнение к моей мессаге
набросал сравнивалку. Но только без hash_map — я щас в отпуске а дома только VC6 со стандартным STL
В общем случае ternary в 3-5 раз быстрее patricia. Тестил на русских текстах и на телефонном справочнике (список ФИО).
Но при этом в ternary пробежаться по списку строк никак нельзя — надо их самому хранить отдельно. Что увеличивает требования к памяти.

947494 уникальных слов

вставка слов из файла
Patricia: 14.368569 sec. 8788 ticks per call 110.5Mb
Ternary: 4.221286 sec. 2597 ticks per call 68.4Mb (чистое дерево, сами строки не хранятся)

повторное чтение файла и поиск слов в map
Patricia: 17.433085 sec. 10662 ticks per call
Ternary: 2.179576 sec. 1341 ticks per call
trie_map & trie_set, v0.07
От: R.K. Украина  
Дата: 12.09.05 21:13
Оценка:
Привет всем!

trie_map &amp; trie_set, v0.07 (MSVC 7.1)
Изменения:


v0.05
Изменения к лучшему:
Отличия от set и map: некоторые различия в работе методов lower_bound и подобных. Обусловлены отсутствием предиката и присутствием бит-компаратора, а также возможностью бесконечного ключа. Но об этом в будущей документации.
You aren't expected to absorb this
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.