Windows Phone 7 Performans İpuçları

0 dakikada yazıldı

38366 defa okundu

Düzenle

DünWindows Phone 7'de performans metriklerinden bahsettikten sonra bugün biraz da performans analizi ve ipuçlarına odaklanmaya karar verdim :) Eğer dünkü yazıyı okumadıysanız kesinlikle önce onu okuyup sonra buradan devam etmenizd büyük fayda olacaktır.

RedrawRegions ile performans analizi

Şimdi bu örneğimizde hemen yeni bir uygulama yaratıyoruz ve ekrana basit bir Ellipse ile Rectangle koyuyoruz.

[XAML]

    \<Canvas x:Name="LayoutRoot" Background="Transparent">\      \<Ellipse x:Name="ellipse" Fill="#FFF4F4F5" Height="128" Canvas.Left="179" Stroke="Black" \         Canvas.Top="249" Width="119"/>\      \<Rectangle x:Name="rectangle" Fill="#FFF4F4F5" Height="794" Stroke="Black" Width="100"/>\     \Canvas\>

Yukarıdaki XAML kodunda da görebileceğiniz gibi aslında durum epey basit. Kod tarafında ise basit bir DispatcherTimer ile Rectangle'ımızı alıp ekranın sağına doğru taşıyalım.

[C#]

        System.Windows.Threading.DispatcherTimer Sayac = \                     new System.Windows.Threading.DispatcherTimer();\ \         void MainPage_Loaded(object sender, RoutedEventArgs e)\         {\             Sayac.Tick += new EventHandler(Sayac_Tick);\             Sayac.Interval = TimeSpan.FromMilliseconds(25);\             Sayac.Start();\         }\ \         void Sayac_Tick(object sender, EventArgs e)\         {\             Canvas.SetLeft(rectangle, Canvas.GetLeft(rectangle) + 1);\         }

Herşey çok güzel gözükse de aslında ciddi sorunlarımız var. Bu uygulamayı çalıştırdığınızda Rectangle ile Ellipse çok güzel anime olacak fakat aslında uygulama yapımızda bazı sorunlar nedeniyle ciddi performans kaybediyoruz. Gelin şimdi hemen aşağıdaki ayarı yapalım.

[C#]

        public App()\         {\             UnhandledException += Application_UnhandledException;\ \             if (System.Diagnostics.Debugger.IsAttached)\             {\                 Application.Current.Host.Settings.EnableFrameRateCounter = true;\                 Application.Current.Host.Settings.EnableRedrawRegions = true ;\             }\ \             InitializeComponent();\             InitializePhoneApplication();\         }

App.xaml arkasında kodumuza Debugger attached durumdaysa çalıştırılmak üzereEnableRedrawRegions  özelliği True olarak değiştiren bir kod ekliyoruz. Böylece artık uygulamamız çalıştığında emülatör veya telefon üzerinde ekranda sürekli "tekrar" çizilen kısımları görebileceğiz.

Hmm kocaman alan tekrar çiziliyor
gibi...Hmm kocaman alan tekrar çiziliyor gibi...

Yukarıdaki sarı olarak gördüğünüz alan Rectangle sola oynadıkça tekrar çizilen alanı gösteriyor. Tabi screenshot'tan anlamak biraz zor ama eğer uygulamayı siz çalıştırırsanız göreceksiniz ki yukarıda sarı olarak gösterilen alan sürekli renk değiştiyor. İşte sistem zaten bu şekilde tekrar çizilen alanları sürekli farklı renklerde renklendirerek bizi tekrar çizilme işleminden haberdar etmeye çalışıyor.

Şimdi esas soru şu :) Neden Rectangle sağa giderken soldaki (uzaktaki) dairyi de içine alan koca bir alanın tekrar çizilmesi söz konusu olmuş olabilir ki? İşte tam da bu noktada UIThread'in yarattığı ve Composition Thread'e aktardığı yüzeyleri hatırlamanızı istiyorum. Her iki nesne de aynı Canvas içerisinde ve Composition Thread kendisine beraber gelen bu arkadaşları tek bir yüzey olarak birleştirip işlem yapmayı uygun görmüş. Bu mekanizmayı değiştiremesek de ortaya saçma bir sonuç çıktığı kesin. Eğer rectangle hareket ediyorsa sadece Rectangle çizilsin. Hatta Rectangle da tekrar çizilmesin Cache'lensin çünkü onun da sadece pozisyonu değişiyor :)

CacheMode ile herşey
yolunda!CacheMode ile herşey yolunda!

İşte Rectangle nesnesinin CacheMode özelliğini değiştirdiğimiz gibi yukarıdaki şekilde nesnelerin ayrı ayrı ele alındığında ve hatta (screenshotta belli olmuyor ama) Rectangle'ın tekrar tekrar render edilme hikayesinin de sonlandığını görebiliyoruz.

[XAML]

    \\      \ \             Stroke="Black" Canvas.Top="249" Width="119"/\>\         \ CacheMode="BitmapCache"  x:Name="rectangle" \             Fill="\#FFF4F4F5" Height="794" Stroke="Black" Width="100"/\>\     \\>

CacheVisualization

Bir diğer önemli nokta ise Cache'lenmiş alanları görmek. Aynı şekilde bu özellikl de yukarıdaki örneğimizindeki gibi sorunları rahatlıkla yakalamanıza yardımcı olabilir. CacheVisualization bir uygulama içerisind Cachelenmiş alanları maviye boyayarak gösteriyor.

[C#]

                Application.Current.Host.Settings.EnableCacheVisualization = true;

CacheVisualization'ı açmak için yukarıdaki komutu kullanabilirsiniz.

Rectangle'daki CacheMode değişikliklierinin
yansıması.Rectangle'daki CacheMode değişikliklierinin yansıması.

Yukarıdaki iki ayrı ekran görüntüsünde de görebileceğiniz üzere solda Rectangle'ın CacheMode kapalıyken Cache' alınan şey tüm yüzey olmuş. Buradan da yüm yüzeyin Composition Thread'e beraber gönderildiğini anlayabiliyoruz. Diğer yandan sağ tarafta Rectangle için ayrıca CacheMode belirlediğimizde de mavi olarak gösterilen yerler ayrı ayrı nesneler olduğu için Cache'lenmenin nerelerde olduğunu anlayabiliyoruz.

Umarım bu analizlerle uygulamalarınızı daha performanslı hale getirebilirsiniz ;) Kolay gelsin.