Как быстро читать и писать в списке в Delphi? - PullRequest
8 голосов
/ 20 ноября 2010

В delphi есть просмотр списка с несколькими полями. Поток проверяет и добавляет элементы в просмотр списка. Если есть та же самая подпись, целое число будет добавлено в подзаголовок этой подписи. Когда количество предметов меньше 2000, производительность в порядке. При проверке и добавлении элементов, а количество элементов превышает 2000, производительность низкая. Когда количество элементов превышает 20 000, производительность можно охарактеризовать как крайне медленную. Есть ли способ быстрого чтения и записи в режиме просмотра списка, когда количество элементов может достигать 50 000 или 100 000?

Большое спасибо заранее

Edit:

Мы прочитали все ваши ответы и благодарим всех за помощь.

Ответы [ 6 ]

11 голосов
/ 20 ноября 2010

Элемент управления Delphi TListView является оболочкой для компонента представления списка Windows.В режиме работы по умолчанию копии данных списка передаются из вашего приложения в элемент управления Windows, и это происходит медленно.

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

Элемент управления Delphi TListView предоставляет виртуальные списки с помощью свойства OwnerData.Вам придется несколько переписать код представления списка, но это действительно единственное решение.

9 голосов
/ 20 ноября 2010

Вам просто нужно использовать свой список в «виртуальном» режиме.

  1. Поместите TListBox в форму;
  2. Установите для свойства Style значение lbVirtual.
  3. Установите для свойства Count количество элементов в вашем списке.
  4. Затем используйте обработчик OnData для предоставления текста, который будет отображаться по запросу:

Как в этом коде (замените некоторыми данными из вашей базы данных или TStringList или тому подобное):

procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer;
  var Data: String);
begin
  Data := Format('Item %d',[Index+1]); // set the text to be displayed
end;

Вы можете дополнительно настроить чертеж, используя стиль lbVirtualOwnerDraw, и вы должны рисовать элементы, используя обработчик события OnDrawItem.В документации Delphi есть некоторый пример кода (по крайней мере, в Delphi 7).;)

В виртуальном режиме вы можете мгновенно отображать 50000 или 100000 элементов.

Для хранения текста использование старого доброго TStringList будет быстрее, чем метод Items элемента TListBoxпотому что это свойство Items [] должно будет взаимодействовать с Windows с «медленными» сообщениями GDI для каждого элемента, тогда как TStringList будет просто сохранять текст в куче Delphi, что обычно намного быстрее.

6 голосов
/ 20 ноября 2010

Вы можете вызывать BeginUpdate и EndUpdate для просмотра списка, чтобы повысить производительность, предотвращая перерисовку списка при обновлении. Но это, вероятно, не даст вам импульс, который вы хотите. Кроме того, вам нужно знать, что доступ к элементам управления VCL напрямую из потока небезопасен, если не синхронизирован.

Я думаю, что было бы лучше пропустить просмотр списка и выбрать сторонний элемент управления, например Virtual Tree View , который является одновременно и отличным, и бесплатным. :)

3 голосов
/ 21 ноября 2010

BeginUpdate и EndUpdate абсолютно необходимы при обновлении элементов. Из вашего описания это звучит так, как будто вы просматриваете элементы в поисках определенной надписи. Это медленно и станет более заметным с большими объемами данных, очевидно.

Поскольку вы ищете подходящую подпись, используйте функцию listviews FindCaption .

Это делает вызов Windows для поиска элементов и довольно быстрый и простой. Если он находит его, он передает элемент назад, и вы можете сослаться на него, чтобы обновить подпункт. В противном случае создайте новый элемент и продолжите обработку.

Пока ваш поток безопасен, и вы должны видеть приличную производительность.

НТН.

3 голосов
/ 20 ноября 2010

Несколько лет назад мы обнаружили, что в дополнение к BeginUpdate / EndUpdate изменили ViewStyle ListView на vsIcon перед добавлением в него больших объемов данных и обратно на vsRepord после того, как мы значительно повысили производительность. Это было в Windows 98 и Windows 2000, если я правильно помню, поэтому я не уверен, что это все еще так.

2 голосов
/ 20 ноября 2010

Попробуйте виртуальный ListView, используя обработчик OnData.

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

Другая ваша задача - сохранить ItemCount списка в количестве элементов в списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...