Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация поиска по IDictionary, Подскажите метод 
:(
    Опции темы
axelprog
  Дата 19.3.2008, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 30.1.2007
Где: витебск

Репутация: нет
Всего: нет



Уважаемые форумчане. Нужна ваша помощь...
Есть следующий код на CLI

Код

for each(ImportDecl^ currImport in imports)    
    {
        for each(System::String^ name in Info::Types->Keys)
            {
                if(Info::Types[name]->FullName->ToUpper()->StartsWith(impStr->ToUpper()))
                {
                    весомая обработка данных
                }
            }
    }

где  Info::Types - IDictionary

В среднем получается, что в if заходит порядка 3-4 ТЫСЯЧ раз. Может кто подскажет, как оптимизировать такой поиск?

Это сообщение отредактировал(а) axelprog - 19.3.2008, 17:42
PM MAIL ICQ Skype GTalk Jabber YIM MSN   Вверх
marcusmae
Дата 19.3.2008, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



axelprog, когда скорость работы .NET-овых коллекций становится узким местом, стоит задуматься о переходе на native, например, близким аналогом Dictionary будет std::map. Тем более у Вас уже CLI, значит, даже отдельного mixed-проекта создавать не надо. Или так не годится?

Это сообщение отредактировал(а) marcusmae - 19.3.2008, 21:38


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
axelprog
Дата 20.3.2008, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 30.1.2007
Где: витебск

Репутация: нет
Всего: нет



Беда в том, что этот dictionary приходит из другой либы, написанной на C#, и поменять его без мощного изменения либы не получится. если только в проекте менять его на map. Только не вижу от этого пользы. В мапе разве можно осуществлять поиск по части ключа? Основные тормоза в том, что надо осуществлять поиск то части ключа, а не по полному ключу (см. if в примере)
PM MAIL ICQ Skype GTalk Jabber YIM MSN   Вверх
marcusmae
Дата 20.3.2008, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Цитата(axelprog @  20.3.2008,  15:45 Найти цитируемый пост)
В мапе разве можно осуществлять поиск по части ключа?

Нет. Ну и у Вас это делает функция String::StartsWith(String^), не имеющая отношения к функциям словаря... 

Тогда другой вариант : получите отсортированный массив строковых ключей и создайте из него дерево (деревья) символов. Ну, то есть, чтобы в корнях стояли всевозможные символы, с которых начинаются ключи, ниже - всевозможные символы на второй позиции в строках, ниже - на третьей и т.д. А значениями в узлах дерева положите null или ссылку на соответствующее значения из оригинального словаря. Таким образом Ваш словарь будет проидексирован, как автозаполнение коммандной строки браузера : имея символы части ключа, Вы переместитесь по дереву вниз до некоторого узла, относительно которого нужно будет взять все значения в листьях - они и будут результатом действия if-а. 

Наверно, коряво объясняю?..


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
axelprog
Дата 20.3.2008, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 30.1.2007
Где: витебск

Репутация: нет
Всего: нет



Цитата

Наверно, коряво объясняю?.


Ну может для кого и коряво. А для меня даже черезчур подробно smile

Идею я в принципе понял. нужно подумать над возможностью применения
PM MAIL ICQ Skype GTalk Jabber YIM MSN   Вверх
ivashkanet
Дата 21.3.2008, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Цитата(axelprog @  19.3.2008,  16:29 Найти цитируемый пост)
В среднем получается, что в if заходит порядка 3-4 ТЫСЯЧ раз. Может кто подскажет, как оптимизировать такой поиск?

В большинстве случаев доступ к IDictionary происходит за константное время (как в массиве). Проблемы появлятся при возникновении колиизий. Когда разные элементы хранятся в одной ячейке таблицы (про реализацию можно почитать ниже).

При грамотной функции хэширования (GetHashCode()), которая неплохо реализована для string, и достаточно пустых ячеек чтобы предотвратить возникновение коллизий. Рекомендуют заполнять таблицу не более 70-80% (так сказала Вики), 60% (насколько помню я). 
Можно попробовать ресайзить таблицу после 50%.


ИМХО, в данном случае больше тормозит методы ToUpper() (перебрать все элементы и перевести каждый в верхний регистр), чем доступ к таблице.


Поэтому мои рекомендации:
1) impStr->ToUpper() вынести за цикл(ы) for.
2) Если сами ключи не важны, то можно перебирать сразу значения: Info::Types->Values
3) Если важны -- увеличить размер таблицы
4) попробовать отказаться от ToUpper() вообще.

Цитата(axelprog @  20.3.2008,  14:45 Найти цитируемый пост)
Основные тормоза в том, что надо осуществлять поиск то части ключа, а не по полному ключу (см. if в примере) 

Тут, действительно, лучше реализовать дерево, как советует marcusmae.
Судя по всему FullName логически разделятеся на несколько частей типа: "ParentParentName-ParentName-Name";
И именно по этим ключам формировать дерево.

Но к этому я настоятельно рекомендую прибегнуть только после детальных тестов производительности и после использования всех других (более простых) методов.

P.S. Про хэш таблицу можно почитать здесь.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0494 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.