Windows Phone 7 Performans İpuçları

0 dakikada yazıldı

38442 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]

    <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 CacheMode="BitmapCache"  x:Name="rectangle" 
           
Fill
="#FFF4F4F5" Height="794" Stroke="Black" Width="100"/>
    </Canvas>

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.