Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Контейнер с быстрым поиском по разным полям 
V
    Опции темы
kami
Дата 9.6.2013, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Доброго времени суток, господа!
Есть класс (очень упрощенно):
Код

TmyItem = class(TObject)
public
  property ID: integer; // инвентарный номер, уникальный
  property Name: string; // наименование элемента, уникально
  property ShortName: string; // "общепринятое" наименование, уникально
end;


И контейнер:
Код

 TmyItemContainer = class(TObjectList<TmyItem>)
  public
    property ItemByID[ID: integer]: TmyItem read GetItemByID;
    property ItemByName[Name: string]: TMyItem read GetItemByName;
    property ItemByShortName[ShortName: string]: TMyItem read GetItemByShortName;
  end;


Элементов всего - около 10 тысяч. Часто приходится искать и обрабатывать элементы как по индексу, так и по какому-либо из перечисленных полей, причем - пакетно, по несколько штук.
Поиск по полю выполняется простым перебором. Такого, чтобы искать сразу по нескольким полям - не бывает.
Проблема:
поиск длится долго. AQTime Standart выдает безумные значения в колонке HitCount на TList<TmyItem>.GetItem

Вопрос: как бы это ускорить?
Пока - единственное, что приходит в голову - создать в TItemContainer три "внутренних" TDictionary с ключами по полям ID, Name и ShortName. В Notification TMyItemContainer добавлять/удалять элементы из этих словарей, ну и в функциях GetItemBy... обращаться непосредственно к соответствующему TDictionary...
Не слишком ли я полез в дебри? Может, есть проще способы?

Заранее всем спасибо!

Это сообщение отредактировал(а) kami - 9.6.2013, 21:53
PM MAIL WWW   Вверх
northener
Дата 10.6.2013, 01:46 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

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



А использовать БД никак?


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
kami
Дата 10.6.2013, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(northener @  10.6.2013,  01:46 Найти цитируемый пост)
А использовать БД никак?

Тут всплывают дополнительные проблемы smile
я практически не умею работать с БД (простейшие операторы DML не в счет), да и кроме того - обращение на каждый "чих" к БД - затратная операция. Да, изначально все активные элементы считываются из БД (на самом деле их гораздо больше 10к, но активных - примерно столько). Но в дальнейшем это становится слишком накладно. Кроме того - изначальная архитектура приложения (тут уж я бессилен) не терпит кучи открытых датасетов (тем более, что у таблиц куча взаимосвязей 1:много).

Поэтому - можно считать, что никак. smile 
PM MAIL WWW   Вверх
Illusion Dolphin
Дата 11.6.2013, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Ну тогда делать как БД, т.е. сделать индекс (можно просто по убыванию/возрастанию расположить) по каждому полю и обновлять его по вставке. Поиск - по индексу бинарнм поиском.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Akella
Дата 11.6.2013, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

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



А зачем куча открытых датасетов?
Может можно 1 или 2?
Я бы тоже рекомендовал БД.
Всё-таки там многое уже реализовано.
Не сегодня, так завтра опять пригодится работа с БД.
Может лучше потратить время на изучение SQL?
На самом деле там всё не так уж и сложно.
PM MAIL   Вверх
northener
Дата 12.6.2013, 01:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

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



Цитата(kami @  10.6.2013,  08:42 Найти цитируемый пост)
ут всплывают дополнительные проблемы smile
я практически не умею работать с БД

Поверь мне. Это не сложно. Достаточно один раз решиться прыгнуть в воду. smile
А дальше твой опыт и наши советы помогут.
Уже то что ты знаешь про DML говорит о том, что тебе достаточно сделать только ещё один (максимум два) шаг  и ты научишься работать с БД.
Ведь учиться ты умеешь!


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
kami
Дата 13.6.2013, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(northener @  12.6.2013,  01:26 Найти цитируемый пост)
тебе достаточно сделать только ещё один (максимум два) шаг  и ты научишься работать с БД.

Я, наверное, неправильно выразился. Вернее, не наверное, а точно неправильно smile

Моих знаний по SQL (если быть более точным - то по T-SQL и диалекту MySQL) вполне хватает, чтобы создать нужные таблицы/триггеры/ключи/индексы, выдернуть нужные мне данные и занести новые/изменить существующие.

Правильнее будет сказать, что я не умею работать с БД из Delphi.
Как я действую на текущий момент:
1. Общая архитектура - трехзвенка. Клиент - сервер приложений общаются между собой по TCP (собственная многослойная надстройка)
2. Клиент, после авторизации, запрашивает у сервера приложений актуальные данные. Тот запрашивает БД, читает в TmyItems кучу всего и вся и отдает это "всё и вся" клиенту. Сразу после чтения датасеты закрываются, но контейнер остается жить со всем прочитанным.
3. Клиент что-то там меняет, изменения приходят на сервер приложений, записываются в БД и автоматом рассылаются всем подключенным клиентам, которым эти изменения интересны. Причем - отправляются только изменения, полностью данные не перечитываются, датасеты не открываются.

Вся проблема - в этой рассылке изменений. Потому что сервер приложений (каждое подключение - отдельный поток, вообще ничего не знающий о других) действует так: ага, мне пришло изменение TmyItem с вот таким ID. Он у меня есть? Если нет - создаем новый и Assign его. Если есть - то просто Assign. Потом - отправка клиенту.

Пока экземпляров TmyItem было в районе 150 - это (поиск элемента с таким ID/Name/ShortName) было очень быстро, на несколько порядков быстрее, чем обращаться к БД (такие изменения, требующие рассылки, происходят очень часто, тем более что контейнер TmyItems был свой для каждого подключения. Это было признано более оправданным, чем иметь один на всех и тормозить на синхронизации потоков). Но вот я решил оттестироваться на 10тыс. элементов и понял, что система нагрузку не держит. Вообще.

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

Резюмируя: менять архитектуру мне никто не позволит, остаются только сортировки и Dictionary. 

Всем спасибо за участие, но если есть какие-либо мысли/ссылки - буду благодарен.

Это сообщение отредактировал(а) kami - 13.6.2013, 14:23
PM MAIL WWW   Вверх
PointerToNil
Дата 17.6.2013, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



*


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

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



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

Это сообщение отредактировал(а) PointerToNil - 17.6.2013, 18:50
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




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


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

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