Какой эффективный способ поиска и фильтрации ObservableCollection - PullRequest
2 голосов
/ 04 марта 2010

У меня есть база данных, состоящая из около 1 миллиона записей. Мое приложение часто выполняет инкрементный поиск по этим записям и фильтрует список пользовательского интерфейса. Сценарий больше похож на «поиск по телефону».
В настоящее время я слежу за этим:

  1. Загрузить данные в List<myModel> на уровне источников данных`
  2. Отправьте его в MainViewModel
  3. Загрузка List<myModel> в ObservableCollection<myViewModel> (привязан к ListView)
  4. По ключевому слову отфильтруйте коллекцию ObservableCollection
  5. Пока приложение закрывается, обновите базу данных [Поскольку ObservableCollection также может быть обновляется пользователем]

Мои вопросы:

  • Это эффективный способ?
  • Теперь моя аппликация потребляет от 30 до 50 МБ памяти. Это справедливо?
  • Или вместо этого я должен выполнить поиск в базе данных? [но я не могу пойти на компромисс по скорости]
  • Должен ли я всегда создавать список myModel и загружать его в мою коллекцию ObservableCollection?
  • Также посоветуйте мне технику фильтрации, которая очень подходит для инкрементального поиска (4-я точка). В настоящее время у меня есть GenericList, содержащий всю коллекцию для поиска, и я добавляю отфильтрованные элементы в ObservableCollection, очищая все предыдущие элементы.

Редактировать: Ранее я проверил потребление памяти только с 37k записей. С 250 тыс. Записей потребление памяти составляет более 100 МБ :(. Следовательно, теперь я планировал хранить в памяти только около 10 тыс. Записей. Если это выйдет за рамки, я запросю БД. Есть предложения?

Заранее спасибо, Veer

1 Ответ

2 голосов
/ 04 марта 2010

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

Теперь моя аппликация расходует около От 30 до 50 МБ памяти. Это справедливо?

Это нормально для приложения .net. Вы сразу заметите, что объем памяти сразу после запуска приложения не намного меньше.

Или я должен выполнить свой поиск в вместо базы данных? [но я не могу компромисс по скорости]

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

Однако, если вы можете сохранить весь список в памяти (скажем, он не слишком велик, чтобы запросить его из базы данных за один шаг, или вам все равно нужно показать весь список пользователю), было бы лучше сохранить нетронутая копия списка и копия этого списка, которую вы можете постепенно фильтровать. Поэтому вам необходимо проверить, являются ли ваши критерии поиска подмножеством предыдущих критериев поиска. Если это так, вы можете отфильтровать уже отфильтрованный список, иначе вам нужно отфильтровать нетронутый список. Это может быть эффективно реализовано с использованием оператора LINQ .Where() и, если необходимо, с помощью PLINQ. .Where() показывает O (n) время AFAIK.

Это можно улучшить, используя HashSet с соответствующим ключом.

...