Paneller, render süresi ve performans açısından hangi sırayla en verimli?


127

İstediğim düzen için birden fazla panelin uygun olacağı birçok kez vardır, ancak farklı panel türleri için render sürelerinde bir fark olduğunu biliyorum.

Örneğin, MSDN şunu belirtir:

Nispeten basit Panel, örneğin Canvasbir daha karmaşık sahip olabilir önemli ölçüde daha iyi performans Panelgibi, Grid.

Peki, işleme süresi ve performans açısından, WPF panelleri hangi sırada en verimli?

WPF Panelleri:

  • Canvas
  • DockPanel
  • Grid
  • UniformGrid
  • StackPanel
  • WrapPanel
  • VirtualizingPanel / VirtualizingStackPanel

İnternette bir yerde bunun bir listesini gördüğüme oldukça eminim, ancak şimdi bulamıyorum.

Aradığım ideal cevap, bana en hızlı işlenecekleri sırayla panellerin bir listesini sağlayacaktır. Çocuk sayısının panellerin ne kadar verimli olduğu konusunda büyük bir faktör olduğunu anlıyorum, bu nedenle bu sorunun uğruna, her panelde sadece bir Label/ TextBoxçifti olduğunu varsayın .

Ek olarak, belirli koşullara göre diğerlerinden daha iyi performans gösteren belirli paneller gibi istisnaların bir listesini istiyorum.

Güncelleme

Aşağıdaki kabul edilen yanıta göre özetlemek gerekirse , panel performansı alt öğelerin sayısına ve düzenine dayanmaktadır, ancak genel olarak liste en hızlıdan en yavaşa doğru:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

Ek olarak, ekrana her zaman sığmayan çok sayıda öğe varsa her zaman a VirtualizingPanel/ VirtualizingStackPanelkullanılmalıdır.

Bu listeden bir öğe seçmeden önce daha fazla ayrıntı için aşağıdaki kabul edilen yanıtı okumanızı şiddetle tavsiye ederim .


Sanallaştırma panellerinin her zaman sanallaştırılmayan panellerden daha iyi performans göstereceğini varsaymak saflık mı?
BoltClock

@BoltClock Panelde ne kadar görünmeyen içerik olduğuna bağlı olduğunu düşünüyorum. Çok sayıda görünmeyen öğe varsa,VirtualizingStackPanel kesinlikle daha iyi performans gösterir, ancak panelde görüntülenen tüm öğeler görünürse, bence normal bir panel kullanmak daha iyidir.
Rachel

Teşekkürler. Zaten hepsi görüntülenecekse, öğeleri sanallaştırmanın bir atık olacağı mantıklı geliyor.
BoltClock

Sanallaştırmanın dışında farklı özelliklere sahipler veya ayrı kontroller olmayacaklar. Müşteriye en iyi kullanıcı arayüzünü sağlayan ile giderim.
paparazzo

1
Gözle görülür bir fark olduğundan emin misiniz (Sanallaştırmanın dışında)? Tek yapmaları gereken, nispeten hafif bir düzen algoritması gerçekleştirmek. Takip edecek tüm renderlarla karşılaştırıldığında minicik. Bunu söyledikten sonra, Grid muhtemelen en yavaş olacak (ağırlıklı ölçeklendirme).
Henk Holterman

Yanıtlar:


130

Her panelin performans özelliklerini tanımlamanın, mutlak bir göreceli performans karşılaştırması yapmaya çalışmaktan daha özlü ve anlaşılır olduğunu düşünüyorum.

WPF, içeriği işlerken iki geçiş yapar: Ölç ve Düzenle. Her panel, bu iki geçişin her biri için farklı performans özelliklerine sahiptir.

Ölçü geçişinin performansı en çok, bir panelin hizalamaları (veya bu durumda Otomatik) kullanarak uzatmayı Gridve ardından uzatılan veya otomatik boyutlandırılan çocuk sayısından etkilenir . Arrange geçişinin performansı, farklı çocukların yerleşim yeri ve tabii ki çocuk sayısı arasındaki etkileşimin karmaşıklığından etkilenir.

Zaman zaman, verilen paneller ihtiyaç duyulan düzene kolayca uyum sağlamaz. Her birinin kullanılabilir alanın belirli bir yüzdesine yerleştirilmesi için rastgele sayıda öğeye ihtiyaç duyan bir kontrol oluşturdum. Varsayılan denetimlerin hiçbiri bunu yapmaz. Onlara bunu yaptırmaya çalışmak (ebeveynin gerçek boyutuna bağlanarak) korkunç performansla sonuçlanır. Tuval temelli bir düzen paneli oluşturdum ve minimum çalışmayla istediğim sonucu elde ettim (tuval için kaynağı kopyaladım ve yaklaşık 20 satırını değiştirdim).

Mevcut Paneller:

  • Tuval

    Alt öğeleri, Tuval alanına göre koordinatlara göre açıkça konumlandırabileceğiniz bir alanı tanımlar.

    Kanvas, her bir öğeye statik olarak bir konum atandığından, düzenleme geçişi için tüm paneller arasında en iyi performansa sahiptir. Bu panelde esneme kavramı olmadığı için ölçü geçişi de mükemmel performansa sahiptir; her çocuk basitçe yerel boyutunu kullanır.

  • DockPanel

    Alt öğeleri birbirine göre yatay veya dikey olarak düzenleyebileceğiniz bir alanı tanımlar.

    Dockpanel, öğelerin bir önceki eklenen öğeye göre tek tek eklendiği çok basit bir düzen şemasına sahiptir. Varsayılan olarak, yükseklik veya genişlik öğenin yerel boyutuna göre belirlenir (sırasıyla Üst / Alt ve Sol / Sağ temel alınarak) ve Dockgenişlik veya yükseklik tanımlanmamışsa diğer yön özellik tarafından belirlenir. Ortadan hızlı ölçüm geçişi ve orta ila hızlı düzenleme geçişi.

  • Kafes

    Sütunlardan ve satırlardan oluşan esnek bir ızgara alanı tanımlar.

    Orantılı boyutlandırma veya otomatik boyutlandırma kullanılıyorsa, bu en yoğun performans gerektiren panel olabilir. Alt öğe boyutunun hesaplanması, öğenin yerel boyutunun ve ızgara tarafından belirtilen mizanpajın karmaşık bir kombinasyonu olabilir. Düzen aynı zamanda tüm paneller arasında en karmaşık olanıdır. Önlem geçişi için yavaş ila orta performans ve düzenleme geçişi için yavaş ila orta performans.

  • StackPanel

    Alt öğeleri yatay veya dikey olarak yönlendirilebilen tek bir satırda düzenler.

    StackPanel, alt öğelerini yönünün tersi yönde yerel veya göreli boyutlandırma ve yönelimi yönünde yerel boyutlandırma kullanarak ölçer (hizalama bu yönde hiçbir şey yapmaz). Bu, onu bu alanda orta seviye bir oyuncu yapar. Düzenleme geçişi basit, sadece öğeleri sırayla düzenlemektir. Muhtemelen bu geçiş için en iyi ikinci performans. Ölçü geçişi için orta performans ve düzen geçişi için hızlı performans.

  • VirtualizingPanel

    Alt veri koleksiyonunu sanallaştıran Panel öğeleri için bir çerçeve sağlar. Bu soyut bir sınıftır.

    Kendi sanallaştırma panelinizi uygulamak için temel bir sınıf. Gereksiz bellek ve işlemci kullanımını önlemek için yalnızca görünür öğeleri yükler. Öğeler için ÇOK daha yüksek performanslı. Sınır kontrolü nedeniyle ekrana sığan öğeler için muhtemelen biraz daha az performanslı. SDK, bunun yalnızca bir alt sınıfını sağlar:VirtualizingStackPanel .

  • WrapPanel

    Alt öğeleri soldan sağa sıralı konumda konumlandırır, içeriği içeren kutunun kenarındaki sonraki satıra böler. Sonraki sıralama, Oryantasyon özelliğinin değerine bağlı olarak, yukarıdan aşağıya veya sağdan sola sırayla gerçekleşir.

    Ölçü geçişi, belirli bir satır için en büyük öğenin satırın yüksekliğini belirlediği ve ardından bu satırdaki her öğenin ya kendi yüksekliğini (eğer varsa) ya da satırın yüksekliğini kullandığı biraz karmaşık bir geçiştir. Düzen geçişi basittir, her öğeyi arka arkaya sıraya koymak ve ardından bir sonraki öğe için yeterli yer olmadığında bir sonraki satıra devam etmek. Orta performans ölçüsü geçer. Düzenleme geçişi için orta ila hızlı performans.

Referanslar:

Mümkün Olduğunda En Verimli Paneli Kullanın

Yerleşim sürecinin karmaşıklığı, doğrudan kullandığınız Panelden türetilmiş öğelerin yerleşim davranışına bağlıdır. Örneğin, Grid veya StackPanel denetimi, Canvas denetiminden çok daha fazla işlevsellik sağlar. İşlevsellikteki bu büyük artışın bedeli, performans maliyetlerinde daha büyük bir artıştır. Bununla birlikte, Izgara kontrolünün sağladığı işlevselliğe ihtiyaç duymuyorsanız, Tuval veya özel panel gibi daha az maliyetli alternatifleri kullanmalısınız.

Gönderen Düzen ve Tasarım: Optimize Performans

Düzen sistemi, Çocuk koleksiyonunun her üyesi için iki geçiş, bir ölçü geçişi ve bir düzenleme geçişi tamamlar. Her alt Panel, kendi özel düzen davranışını elde etmek için kendi MeasureOverride ve ArrangeOverride yöntemlerini sağlar.

Önlem geçişi sırasında, Çocuk koleksiyonunun her üyesi değerlendirilir. Süreç, Measure yöntemine yapılan bir çağrı ile başlar. Bu yöntem, üst Panel öğesinin uygulaması içinde çağrılır ve düzenin gerçekleşmesi için açıkça çağrılması gerekmez.

İlk olarak, UIElement'in Klip ve Görünürlük gibi yerel boyut özellikleri değerlendirilir. Bu, MeasureCore'a iletilen constraintSize adlı bir değer oluşturur.

İkinci olarak, FrameworkElement üzerinde tanımlanan çerçeve özellikleri işlenir ve bu da constraintSize değerini etkiler. Bu özellikler genellikle, Yükseklik, Genişlik, Kenar Boşluğu ve Stil gibi temel UIElement'in boyutlandırma özelliklerini açıklar. Bu özelliklerin her biri, öğeyi görüntülemek için gerekli olan alanı değiştirebilir. Daha sonra MeasureOverride, parametre olarak constraintSize ile çağrılır.

Not Yükseklik ve Genişlik ile Gerçek Yükseklik ve Gerçek Genişlik özellikleri arasında bir fark vardır. Örneğin, ActualHeight özelliği, diğer yükseklik girdilerine ve düzen sistemine dayalı olarak hesaplanan bir değerdir. Değer, gerçek oluşturma geçişine dayalı olarak düzen sistemi tarafından belirlenir ve bu nedenle, giriş değişikliğinin temeli olan Yükseklik gibi özelliklerin ayar değerinin biraz gerisinde kalabilir. ActualHeight hesaplanan bir değer olduğundan, yerleşim sistemi tarafından yapılan çeşitli işlemlerin bir sonucu olarak birden çok veya artımlı olarak bildirilen değişiklikler olabileceğini bilmelisiniz. Yerleşim sistemi, alt elemanlar için gerekli ölçü alanını, ana eleman tarafından kısıtlamaları vb. Hesaplıyor olabilir. Önlem geçişinin nihai amacı, çocuğun DesiredSize değerini belirlemesidir. MeasureCore çağrısı sırasında meydana gelir. DesiredSize değeri, içerik düzenleme geçişi sırasında kullanılmak üzere Measure tarafından saklanır.

Düzenleme geçişi, Düzenleme yöntemine yapılan bir çağrı ile başlar. Düzenleme geçişi sırasında, ana Panel öğesi, alt öğenin sınırlarını temsil eden bir dikdörtgen oluşturur. Bu değer, işlem için ArrangeCore yöntemine iletilir.

ArrangeCore yöntemi, alt öğenin DesiredSize değerini ve öğenin işlenmiş boyutunu etkileyebilecek ek kenar boşluklarını değerlendirir. ArrangeCore, Panel'in ArrangeOverride yöntemine bir parametre olarak iletilen bir düzenSize oluşturur. ArrangeOverride, alt öğenin finalSize değerini oluşturur. Son olarak, ArrangeCore yöntemi, kenar boşluğu ve hizalama gibi öteleme özelliklerinin son bir değerlendirmesini yapar ve çocuğu düzen yuvasına yerleştirir. Çocuk tahsis edilen alanın tamamını doldurmak zorunda değildir (ve çoğu zaman da yoktur). Kontrol daha sonra üst Panele döndürülür ve düzen süreci tamamlanır.

Gönderen Çocukları Ölçme ve Düzenleme


1
Artık silinmiş bir yoruma yanıt olarak: Yardımcı olmayacakları için ölçümleri eklemedim. Bir elektronik tablonun yararlı olamayacak kadar çok kombinasyonu var. Performansı optimize etmek için daha kullanışlı bir yöntem, ilk yerleşim panellerini seçmek için genel bir anlayış kullanmak ve ardından gerçek durumun bir analizini kullanarak oradan gerektiği gibi optimize etmek olacaktır.
N_A

Teşekkürler, WPF panellerinin gerçekte nasıl oluşturulduğunu açıklamanız ve her panelin Ölçme / Düzenleme performansı benim istediğimden çok daha iyi :)
Rachel

@mydogisbox UniformGridListenizde hiçbir yerde göremiyorum . Cevabınızı bu panel ile güncelleyebilir misiniz ve diğer panel türlerine göre tahmini performansı Ölç / Düzenle?
Rachel

1
@Rachel UniformGrid, uygulama düzeninde kullanılmak üzere tasarlanmamıştır. Daha fazla bilgi için burada "Türetilmiş Panel Öğeleri" bölümüne bakın: msdn.microsoft.com/en-us/library/ms754152.aspx . Hız açısından a'dan biraz daha hızlı DockPanelve a'dan biraz daha yavaş olmalıdır Canvas.
N_A

12

Belki bu sana yardımcı olur.

Sadece paneller için değil, aynı zamanda WPF'de yapmak istediğiniz her uygulama için.

WPF çizim ve ölçüm performansını tamamlar.

Ayrıca, hedeflemek istediğiniz farklı işletim sistemleri için bir çizim testi uygulaması, sonuçları ve sonuç bilgileri içerir.


8

Bahsettiğiniz paneller Düzen panelleridir, bu nedenle yerleşim sistemine kısa bir genel bakış, bunun muhtemelen en verimli panelin basit bir listesi olmayacağını, verimlilik ve performans üzerinde en büyük etkiye sahip panelleri nasıl kullandığınızı gösterir.

LayoutSystem_Overview :

En basit haliyle, düzen, bir öğenin boyutlandırılmasına, konumlandırılmasına ve çizilmesine yol açan yinelemeli bir sistemdir. Daha spesifik olarak, düzen, bir Panel öğesinin Çocuk koleksiyonunun üyelerini ölçme ve düzenleme sürecini açıklar. Düzen, yoğun bir süreçtir. Çocuk koleksiyonu ne kadar büyükse, yapılması gereken hesaplama sayısı da o kadar fazladır. Karmaşıklık, koleksiyonun sahibi olan Panel öğesi tarafından tanımlanan düzen davranışına göre de tanıtılabilir. Canvas gibi nispeten basit bir Panel, Grid gibi daha karmaşık bir Panelden önemli ölçüde daha iyi performansa sahip olabilir.

Bir alt UIElement pozisyonunu her değiştirdiğinde, yerleşim sistemi tarafından yeni bir geçişi tetikleme potansiyeline sahiptir. Bu nedenle, gereksiz çağırma kötü uygulama performansına neden olabileceğinden, düzen sistemini çağırabilecek olayları anlamak önemlidir. Aşağıda, yerleşim sistemi çağrıldığında meydana gelen süreç açıklanmaktadır.

1. Bir alt UIElement, ilk olarak temel özelliklerini ölçerek düzen sürecini başlatır.

2. FrameworkElement üzerinde tanımlanan boyutlandırma özellikleri, Genişlik, Yükseklik ve Kenar Boşluğu gibi değerlendirilir.

3. Dock yönü veya istifleme Yönü gibi panele özgü mantık uygulanır.

4. İçerik, tüm çocuklar ölçüldükten sonra düzenlenir.

5. Çocuk koleksiyonu ekrana çizilir.

6. Koleksiyona başka Çocuklar eklenirse, bir LayoutTransform uygulanırsa veya UpdateLayout yöntemi çağrılırsa işlem yeniden çağrılır.

Çocukların ölçülmesi ve düzenlenmesi hakkında daha fazla bilgi için LayoutSystem_Measure_Arrange'a bakın .

LayoutSystem_Performance :

Düzen, yinelemeli bir süreçtir. Bir Çocuk koleksiyonundaki her alt öğe, düzen sisteminin her çağrısı sırasında işlenir. Sonuç olarak, gerekli olmadığında yerleşim sisteminin tetiklenmesinden kaçınılmalıdır. Aşağıdaki hususlar daha iyi performans elde etmenize yardımcı olabilir.

Hangi özellik değeri değişikliklerinin yerleşim sistemi tarafından yinelemeli bir güncellemeye zorlayacağının farkında olun.

Değerleri yerleşim sisteminin başlatılmasına neden olabilecek bağımlılık özellikleri genel bayraklarla işaretlenir. AffectsMeasure ve AffectsArrange, hangi özellik değeri değişikliklerinin yerleşim sistemi tarafından yinelemeli bir güncellemeyi zorlayacağına ilişkin yararlı ipuçları sağlar. Genel olarak, bir öğenin sınırlayıcı kutusunun boyutunu etkileyebilecek herhangi bir özellik, true olarak ayarlanmış bir AffectsMeasure bayrağına sahip olmalıdır. Daha fazla bilgi için bkz. Bağımlılık Özelliklerine Genel Bakış.

Mümkün olduğunda, LayoutTransform yerine RenderTransform kullanın.

LayoutTransform, bir kullanıcı arayüzünün (UI) içeriğini etkilemenin çok yararlı bir yolu olabilir. Ancak, dönüştürme efektinin diğer öğelerin konumunu etkilemesi gerekmiyorsa, bunun yerine bir RenderTransform kullanmak en iyisidir çünkü RenderTransform mizanpaj sistemini çağırmaz. LayoutTransform, dönüşümünü uygular ve etkilenen öğenin yeni konumunu hesaba katmak için yinelemeli bir düzen güncellemesini zorlar.

UpdateLayout'a gereksiz çağrılardan kaçının.

UpdateLayout yöntemi, özyinelemeli bir düzen güncellemesini zorlar ve genellikle gerekli değildir. Tam bir güncellemenin gerekli olduğundan emin değilseniz, bu yöntemi sizin için çağırması için düzen sistemine güvenin.

Büyük bir Çocuk koleksiyonuyla çalışırken, normal bir StackPanel yerine VirtualizingStackPanel kullanmayı düşünün.

Alt koleksiyonun sanallaştırılmasıyla VirtualizingStackPanel yalnızca şu anda ebeveynin ViewPort'unda bulunan nesneleri bellekte tutar. Sonuç olarak, çoğu senaryoda performans önemli ölçüde iyileştirilir.

Performansı Optimize Etme: Düzen ve Tasarım : Bu makale, ağacın verimli bir şekilde nasıl oluşturulacağına dair ayrıntılara giriyor ve karmaşıklıklarına göre basit bir panel listesi veriyor.

Tuval (en az karmaşıkt = daha verimli ve daha iyi performans)

Kafes

Diğer Paneller (daha karmaşık = daha az verimli ve daha kötü performans)

Dikkat edilmesi gereken diğer performans konuları: WPF kullanıcı arayüzü oluşturma hızını iyileştirmenin yolları

  1. Her şeyi önbelleğe alın. Fırçalar, Renkler, Geometriler, Biçimlendirilmiş Metinler, Glifler. (Örneğin iki sınıfımız var: RenderTools ve TextCache. Her birimin adreslerinin her iki sınıfın paylaşılan örneğine işlenmesi. Yani iki grafikte aynı metin varsa, hazırlığı yalnızca bir kez yürütülür.)
  2. Uzun süre kullanmayı planlıyorsanız, Dondurulabilir. Özellikle geometriler. Karmaşık çözülmemiş geometriler, HitTest'i son derece yavaş yürütür.
  3. Her bir ilkeli oluşturmanın en hızlı yollarını seçin. Örneğin, metin oluşturmanın yaklaşık 6 yolu vardır, ancak en hızlısı DrawingContext.DrawGlyphs'dir.
  4. Konteyner Geri Dönüşümünü etkinleştirin. Sanallaştırma birçok performans iyileştirmesi getiriyor, ancak kaplar atılacak ve yeniden oluşturulacak, bu varsayılandır. Ancak VirtualizingStackPanel.VirtualizationMode = "Recycling" ayarlayarak konteynırları geri dönüştürerek daha fazla performans elde edebilirsiniz.
  5. Gönderen burada : başvurunuz destekleyebilir iç içe miktarına pratik bir sınır yoktur, ancak, sadece gerçekte istenilen düzen için gerekli olan şu panelleri kullanmak için uygulama sınırlamak için genellikle en iyisidir. Çoğu durumda, bir yerleşim kabı olarak esnekliği nedeniyle iç içe paneller yerine bir Izgara öğesi kullanılabilir. Bu, gereksiz öğeleri ağaçtan uzak tutarak uygulamanızdaki performansı artırabilir.

2
Bu cevap neredeyse tamamen başka kaynaklardan kopyalayıp yapıştırmaktan ibarettir, bazıları ilişkilendirilmemiştir. Sadece ilgili kısımlara indirip, tüm kaynakları doğru bir şekilde atfederseniz ve soruyu daha doğrudan cevaplamaya çalışsanız çok daha iyi olur.
N_A

2
@mydogisbox Cevap bir bilgi derlemesidir, cevabınızda kullandığınız sitelerin çoğu, ekleyebilirim. Performans değişikliğinin eksik bir cevaba yol açabileceği veya soruyu soranın hala ek soruları olmasına yol açabilecek diğer yönleri dikkate almamak için onları dahil etmeyi seçtim. İnanılmaz bir 21.7K temsilciye ve çok sayıda WPF deneyimine sahip Rachel bu bilgiyi zaten biliyor olsa da, bu soruya bakan diğerleri yanıtla birlikte bu ek ve ilgili bilgiyi isteyebilir.
Erick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.