Nasıl bir liste Görünümü öğeler ekleme hız için?
Win bir liste Görünümü için bin (örn: 53,709) birkaç parça daha ekliyorum.
Deneme 1: 8**
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
Bu çok kötü bir şekilde çalışır. Bariz ilk düzeltme BeginUpdate/EndUpdate
aramak.
Girişimi 2: 3,106 ms
listView.BeginUpdate();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
listView.EndUpdate();
Bu daha iyi, ama hala büyüklük çok yavaş bir emirdir. Ekleyerek ListViewİtems gelelim ayrı yaratılış ListViewİtems, gerçek suçluyu bulana kadar:
Girişimi 3: 2,631 ms
var items = new List<ListViewItem>();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
items.Add(item);
}
stopwatch.Start();
listView.BeginUpdate();
foreach (ListViewItem item in items)
listView.Items.Add(item));
listView.EndUpdate();
stopwatch.Stop()
Gerçek darboğaz öğeler ekliyor. Hadi AddRange
yerine foreach
bir dönüştürme deneyin
Girişimi 4:2,182 ms
listView.BeginUpdate();
listView.Items.AddRange(items.ToArray());
listView.EndUpdate();
Biraz daha iyi. Bu darboğaz ToArray()
içinde olmadığından emin olalım
Girişim 5:2,132 ms
ListViewItem[] arr = items.ToArray();
stopwatch.Start();
listView.BeginUpdate();
listView.Items.AddRange(arr);
listView.EndUpdate();
stopwatch.Stop();
Sınırlama liste görünümü öğeler ekleme gibi görünüyor. Biz ekliyoruz AddRange
, diğer bir aşırı yüklenme ListView.ListViewItemCollection
bir dizi yerine belki
Girişim 6:2,141 ms
listView.BeginUpdate();
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(listView);
lvic.AddRange(arr);
listView.EndUpdate();
Ama bu hiç iyi değil.
Şimdi dinlenme zamanı
Adım 1- hiçbir sütun için ayarlanmış olduğundan emin olun< . em ^"otomatik genişlik":
Kontrol edin
Adım 2- Liste Görünümü öğesi eklemek her zaman sıralamak için çalışıyor olmadığından emin olun:
Kontrol edin
Adım 3- Stackoverflow sor:
Kontrol edin
Not:Belli ki bu liste Görünümü musun beri sanal modunda değil; mi/olamaz "" sanal liste görünümü öğeleri (VirtualListSize
ayarlayın). Ekle Neyse benim sorum sanal modunda bir liste görünümü hakkında değil.
Liste görünümü çok yavaş olduğu için öğeler eklemek için hesap olabilir kaçırdığım bir şey var mı?
Bonus Gevezelik
Windows Liste Görünümü sınıf 394 ms
bu kod yazabilirim, çünkü daha iyi, biliyorum:
ListView1.Items.BeginUpdate;
for i := 1 to 53709 do
ListView1.Items.Add();
ListView1.Items.EndUpdate;
eşdeğer C ile kıyaslandığında# kod 1,349 ms
:
listView.BeginUpdate();
for (int i = 1; i <= 53709; i )
listView.Items.Add(new ListViewItem());
listView.EndUpdate();
büyüklükte bir sipariş daha hızlı.
Ne özelliği Win Liste Görünümü sarıcı mi kaçırdım?
CEVAP
Ve performans 4 faktör tarafından yavaş yapabilir birkaç şey fark ettim görüntüleyin kadar görmüş olduğunuz liste için kod: kaynak bir göz attım
Liste Görünümü.cs, ListViewItemsCollection.AddRange
benim denetim başladığım yer olan ListViewNativeItemCollection.AddRange
çağırır
ListViewNativeItemCollection.AddRange
(satır: 18120) iki geçer tüm koleksiyonu değerleri, toplamak tüm kontrol öğeleri başka bir 'geri' onlardan sonra InsertItems
denir (ikisi de korunan bir kontrol karşı owner.IsHandleCreated
sahibi olmak ListView
) çağrı BeginUpdate
.
ListView.InsertItems
(satır: 12952), ilk olarak, tüm liste başka bir geçiş var o zaman ArrayList arayın.AddRange (muhtemelen bir geçiş daha var) ondan sonra da bir geçiş olarak adlandırılır. Lider
ListView.InsertItems
(satır: 12952), Ara () EndUpdate
) başka bir geçitten nereye eklenir HashTable
Debug.Assert(!listItemsTable.ContainsKey(ItemId))
yavaş daha fazla hata ayıklama modu. Eğer tanıtıcı oluşturulan değil, ArrayList
, listItemsArray
if (IsHandleCreated)
, sonra bir çağrı için öğeleri ekler
ListView.InsertItemsNative
(satır: 3848) son aslında doğal görünümü eklenir nereye listesinde geçiyor. Debug.Assert(this.Items.Contains(li)
ayrıca hata ayıklama modunda performans yavaşlatacaktır.
Bu öğelerin tüm liste boyunca ekstra paslar var .net hiçbir şey yerli liste görünümü öğeleri ekleme ulaşmadan kontrol. Geçer bazı eğer oluşturulmadan önce tanıtıcı öğeleri ekleyebilirsiniz, size biraz zaman kazandırabilir böylece yaratılan Ele karşı çekler tarafından korunuyor. OnHandleCreated
yöntemi listItemsArray
aramalar InsertItemsNative
doğrudan tüm ekstra gürültü patırtı olmadan alır.
source reference Kendin indirip bir göz atabilirsiniz, belki bir şeyler kaçırdım.
İşte bir blog yazısı ve diğer şeylerin ListView performance, tartışıyor. Daha hızlı işlemek önce öğeleri eklemek için oluşturulan, ancak denetim işlenirken bir bedel ödeyecek ettiğini göstermektedir. Belki işleme iyileştirmeleri açıklamalarda belirtilen uygulama ve kolu önce öğeleri oluşturulur ekleyerek her iki dünyanın en iyi olsun.
Edit: çeşitli şekillerde bu hipotezi Test edilmiş ve kolu oluşturmadan önce öğeleri ekleme suuuper hızlı iken, kolu oluşturmak için gittiğinde katlanarak daha yavaş olur. Bu kolu oluşturmak için kandırmaya çalışıyorum ile oynadım, bir şekilde tüm ekstra geçirir geçmeden İnsertİtemsNative diyebilir o zaman, ama ne yazık ki bertaraf oldum. Tek şey istiyorum acaba mümkün olabilir, oluşturmak için Win32 görüntüsünde bir c projesi, eşyaları öğeleri ve kullanım çengel için yakalama Kuyruk ileti ile gönderilen Liste Görünümü oluştururken onun başa geçmesi ve tekrar başvuru için win 32 Liste Görünümü yerine, yeni bir pencere.. ama kim bilir ne gibi yan etkiler olur... win 32 guru için ne yapmalıyım konuş hakkında çılgın bir fikir :)
Nasıl Android Liste Görünümü ayırıcı ç...
Nasıl Android liste görünümü yenilemek...
nasıl bir aktivite verileri ile liste ...
Nasıl kapalı (dairesel) bir liste Görü...
Nasıl fotoğraf listesini görüntülemek ...