2010-03-17 12 views
18

Sto facendo un po 'di benchmark per determinare se posso usare WPF per un nuovo prodotto. Tuttavia, i primi risultati delle prestazioni sono deludenti. Ho creato un'app rapida che utilizza l'associazione dati per visualizzare un gruppo di testo casuale all'interno di una casella di riepilogo ogni 100 ms e si stava consumando circa il 15% di CPU. Così ho fatto un'altra app rapida che saltava lo schema di data binding/data template e non fa altro che aggiornare 10 TextBlocks che si trovano all'interno di un ListBox ogni 100 ms (il prodotto attuale non richiederebbe aggiornamenti di 100 ms, più come 500 ms max, ma questo è un test di stress). Sto ancora vedendo ~ 5-10% di utilizzo della CPU. Perché è così alto? È a causa di tutti i fili della spazzatura?Si prevede questa prestazione WPF TextBlock lenta?

Ecco il codice XAML per la versione che non utilizza vincolante:

<Grid> 
    <ListBox x:Name="numericsListBox"> 
     <ListBox.Resources> 
      <Style TargetType="TextBlock"> 
       <Setter Property="FontSize" Value="48"/> 
       <Setter Property="Width" Value="300"/> 
      </Style> 
     </ListBox.Resources> 

     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
    </ListBox> 
</Grid> 

Ecco il codice dietro:

public partial class Window1 : Window 
{ 
    private int _count = 0; 

    public Window1() 
    { 
     InitializeComponent(); 
    } 

    private void OnLoad(object sender, RoutedEventArgs e) 
    { 
     var t = new DispatcherTimer(TimeSpan.FromSeconds(0.1), DispatcherPriority.Normal, UpdateNumerics, Dispatcher); 
     t.Start(); 
    } 

    private void UpdateNumerics(object sender, EventArgs e) 
    { 
     ++_count; 
     foreach (object textBlock in numericsListBox.Items) 
     { 
      var t = textBlock as TextBlock; 
      if (t != null) 
       t.Text = _count.ToString(); 
     } 
    } 
} 

che consuma ~ 5-10% della CPU in base al Task Manager, o fino a circa il 20% di uno dei nuclei! Qualche idea per un modo migliore per rendere rapidamente il testo?

Il mio computer: XP SP3, 2,22 GHz Core 2 Duo, 4 GB di RAM, grafica integrata Intel 4500 HD. E questo è un ordine di grandezza più potente dell'hardware che avrei bisogno di sviluppare nel prodotto reale.

+0

Nel binding WPF non è esattamente il modo in cui l'hai fatto a proposito. –

+0

Non ho inserito il codice per la versione che ha utilizzato l'associazione (e anche il pattern MVVM). Ho pensato che questa versione sarebbe ancora più leggera e rappresenta un esempio migliore. –

+0

La maggior parte dei cicli della CPU dovrebbe essere masterizzata sul rendering qui. Ma usa un profiler per essere sicuro. Ecco una recensione del tuo hardware grafico * very * poky: http://pcgamingcorner.com/wordpress/?p=820 –

risposta

40

Questa normale prestazione di TextBlock è normale?

No. Tali prestazioni di TextBlock lente sono decisamente non normali. La mia esperienza è stata che TextBlocks è molto più veloce di così.

Ho eseguito diversi test utilizzando il codice che hai postato, lasciando l'intervallo di aggiornamento a 0.1 secondi e variando l'hardware e il numero di TextBlocks. Ecco cosa ho trovato:

10 TextBlocks, 2.16GHz Core 2 Duo, Radeon 4100 GPU:  CPU Usage "0%" 
10 TextBlocks, 2.16GHz Core 2 Duo, Software rendering: CPU Usage 1% 
100 TextBlocks, 2.16GHz Core 2 Duo, Radeon 4100 GPU:  CPU Usage 8% 
100 TextBlocks, 2.16GHz Core 2 Duo, Software rendering: CPU Usage 18% 
10 TextBlocks, 200MHz Pentium Pro, Software rendering: CPU Usage 35% 
10 TextBlocks, 200MHz Pentium Pro, No rendering:  CPU Usage 7% 

Ognuno di questi test suggerisce che WPF è di circa 10 volte più velocemente le vostre misure indicano. Se il tuo codice è così semplice come sembra, il mio sospetto sarebbe che ci sia qualcosa di strano con i tuoi driver GPU o DirectX.

Si noti che per i 100 test di TextBlock ho dovuto effettuare tre modifiche: aggiungere 90 blocchi di testo, impostare ItemsPanel su un WrapPanel per ottenere i dati in colonne e ridurre la larghezza di TextBlock per ottenere tutto ciò che si adatta allo schermo.

Il mio test sul Pentium Pro 200 MHz è probabilmente il più rilevante per l'hardware incorporato. Se l'applicazione aggiorna 10 blocchi di testo ogni 0,5 s, è possibile utilizzare circa il 3% della CPU per l'aggiornamento e il ridisegno su una CPU a 200 MHz.

E se volessi renderlo ancora più veloce?

L'utilizzo di un elenco di TextBlocks con associazione dati è molto comodo, ma WPF offre anche meccanismi di livello inferiore che possono essere utilizzati quando è necessario il massimo delle prestazioni.

Un TextBlock WPF contiene in realtà un documento formattato non solo una stringa, quindi è una struttura di dati molto complessa. È abbastanza semplice scrivere il proprio controllo TrivialTextBlock che ha un parametro stringa e lo disegna semplicemente usando le proprietà TextElement ereditate (come FontSize, FontWeight, ecc.). Questo di solito non è fatto perché TextBlock è abbastanza veloce per quasi tutti gli scopi.

Un'altra considerazione è che ogni volta che si modifica il testo in un TextBlock, WPF ricalcola il layout. A differenza delle tecnologie meno recenti, il contenuto di un TextBlock WPF può facilmente modificare il layout dell'interfaccia utente. Quindi il testo deve essere rimisurato e riformattato ogni volta che lo cambi. La creazione del suddetto controllo TrivialTextBlock può velocizzare anche questo risolvendo le dimensioni del controllo e quindi evitando passaggi di layout.

Una terza considerazione è che formattatore testo di WPF ha funzioni tipografiche avanzate, sostenendo cose come la crenatura, testo bidirezionale, legature, le caratteristiche Unicode, font personalizzati, ecc Per ottenere il massimo delle prestazioni in assoluto in WPF si può ignorare il formattatore di testo interamente e disegna il tuo testo come una serie di immagini. Ciò richiede circa 20 righe di XAML e circa 40 righe di codice C#.

Tutte queste ottimizzazioni sono possibili, ma nel tuo caso non mi preoccuperei di farlo: farne un semplice utilizzo della CPU del 3% probabilmente non ne vale la pena.

+0

Wow, è stata una risposta incredibilmente utile e completa, e ha davvero reso la mia giornata. Grazie Ray. Ho installato un altro PC con una CPU Atom con Windows 7. Lo stesso programma che viene eseguito con una CPU del 5-10% sulla mia workstation viene eseguito con CPU 0% su questo PC. Sulla mia workstation c'è sicuramente qualcosa con la mia scheda video/driver. O quello o forse il rendering WPF è solo molto più veloce in Windows 7 rispetto a XP. Grazie per il suggerimento sugli aggiornamenti di TextBlock che invocano il sistema di layout, lo terrò sicuramente a mente. Buona giornata! –

4

C'è molto che si può sbagliare in WPF, per quanto riguarda le prestazioni. Molte persone si avvicinano come un'applicazione di moduli di vincita, una pagina Web html o qualche attacco ibrido allo sviluppo dell'applicazione e per questo ci sono molte valutazioni errate di WPF.

Capisco che si stia tentando di eseguire test delle prestazioni per verificare se un WPF può funzionare per la propria piattaforma e un buon esempio di come eseguire il controllo delle applicazioni WPF per il tipo di carico che si prevede possa essere trovato in il link sottostante

http://msdn.microsoft.com/en-us/magazine/dd483292.aspx

Petzold guida l'utente attraverso il processo di ottimizzazione di un elementi di controllo per rendere in modo ottimale per il carico di dati che vengono visualizzati sull'interfaccia utente.

Per fare un test equo vorrei scrivere un'applicazione di esempio che si occupa di un campione dei dati con cui si avrà a che fare e quindi testare le prestazioni di quel codice. Ci sono un gran numero di ottimizzazioni che possono essere applicate per far urlare un'applicazione WPF e utilizzare meno CPU, ma dipendono tutte dalla tua applicazione e da come essa rappresenta i tuoi dati.

Spero che questo aiuti.

+0

Bene, per me, uno dei principali punti di forza del WPF è che consente di lavorare a un livello più alto di astrazione, con la speranza di ottenere un miglioramento della produttività. Ma se (presumibilmente) cose semplici come questa portano ad un elevato carico della CPU, e hai bisogno di scavare per farlo funzionare bene, allora quel vantaggio di produttività inizia a svanire. Dovrò fare ancora qualche ricerca, sembra. –

+0

Può portare a una maggiore produttività, ma è necessario passare attraverso una curva di apprendimento su cosa e come utilizzare WPF. Una volta che si passa attraverso la velocità in cui è possibile creare un'applicazione è veloce. Ho creato alcune applicazioni con WPF e attualmente sto lavorando a un'applicazione di livello enterprise con WPF e il tempo di sviluppo è molto più breve di quello che sarebbe stato con altre piattaforme e la flessibilità ottenuta è ottima. –

3

Utilizzare WPF solo per un nuovo prodotto se si è certi che l'hardware di implementazione sia abbastanza buono. In pratica, penso che una scheda grafica dedicata sia un requisito minimo.

Il mio team ha selezionato WPF per un progetto destinato a una piattaforma di processore Atom perché la grafica GMA 500 integrata ha richiesto il rendering di WPF Livello 2. Tuttavia, per qualche motivo le prestazioni di GMA 500 sono molto lente e abbiamo disattivato il rendering dell'hardware in ottenere prestazioni migliori. Anche allora, la piattaforma Atom è sottodimensionata per prestazioni ragionevoli. Vi consiglio di non usare WPF se i netbook o qualsiasi altra cosa con Intel Atom fa parte della vostra base di clienti.

Here is a link a una domanda che ho aperto sul rendimento del WPF sulla GMA 500.

Come suggerisce Rob Perkins, potrebbe essere meglio con Silverlight 4 per migliorare le prestazioni.

Buona fortuna!

+0

Grazie per l'input. Siamo stati in grado di cavarcela con un Atom dual core più recente. Gestisce due display con grafici vettoriali in tempo reale e diversi TextBlocks che aggiornano frequentemente con pochi problemi. La composizione memorizzata nella cache di WPF4 ha aiutato molto la creazione di grafici. Anche l'esecuzione su Windows 7 con Aero disabilitato ha aiutato molto. Abbiamo circa il 1-3% di carico della CPU allo steady state e l'interfaccia utente è molto reattiva. Le animazioni sono decisamente stuttery rispetto al mio portatile GPU Core i7/nVidia, ma l'esperienza dell'utente non soffre molto. –

Problemi correlati