Как быстро читать и писать в listview на delphi?



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



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



Правка:



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

6 ответов:

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

  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, что обычно намного быстрее.

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

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

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

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

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

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

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

Так как вы ищете соответствующий заголовок, используйте функцию listviews FindCaption.

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

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

HTH.

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

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

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

Comments

    Ничего не найдено.