DrawString: starke Performance-Schwankungen

29/10/2009 - 21:45 von Armin Zingler | Report spam
Hi,

ich habe hier ein Panel (Winforms). In dessen Paint-Ereignis gebe ich
per DrawString Text aus. Es handelt sich um ein Raster mit 11 Zeilen
und 18 Spalten, also 198 Zellen. Pro Zelle wird lediglich ein Buchstabe
ausgegeben. Diese 198 DrawString-Aufrufe dauern 0,25s. Man kann also zusehen,
und das ist zu langsam. Das Panel wird Timer-gesteuert alle 0,5s neu
gezeichnet (panel.invalidate im Tick-Ereignis).

Dann habe ich mit verschiedenen Einstellungen für graphics.textrenderinghint
herumgespielt. Mit 'SingleBitPerPixel' ergab sich eine Beschleunigung
auf 0,004s. Beim nàchsten Start - ohne Codeànderung - waren es
aber wieder 0,25s. Mit 'AntiAlias' waren es auch erst 0,004s dann aber auch
wieder 0,25s. Hat also nichts mit dieser Einstellung zu tun sondern das
war purer Zufall.

Ein anderes Mal habe ich die Form minimiert und wiederhergestellt und konnte
dadurch die 0,004s wiederherstellen. Aber auch das ist nicht zuverlàssig
nachvollziehbar.

Reproduzierbar ist lediglich, dass nach Öffnen und Schließen des Fenstermenüs
(Klick links oben oder Alt+Leer) die 0,004s immer hergestellt werden können.
Bereits beim Öffnen des Fenstermenüs ist diese Beschleunigung zu beobachten.

Das ganze làuft auf einem Dual-Core, wobei ein Core bereits durch einen anderen
Thread voll ausgelastet ist. Somit ergibt sich im "Fehlerfall" eine gesamte
CPU-Auslastung von 75%, also Core00% und Core1P%. Nach Öffnen des Fenstermenüs,
also wenn die Langsamkeit verflogen ist, sind es nur noch rund 50% (Core00%,
Core1 gegen 0%) da die Textausgabe fast nicht mehr ins Gewicht fàllt.
Ich dachte nàmlich zuerst, dass der GC noch eine Rolle spielt weil der Worker-Thread
viel Müll produziert. Aber da sind ja noch Ressoursen frei, d.h. das ist
auch nicht die Ursache.

Ich gehe den Dingen schon gerne auf den Grund aber hierzu fàllt mir momentan nichts
mehr ein. Hat jemand schon mal dieselbe Beobachtung gemacht? Evtl mit ner zugehörigen
Ursache?


Armin
 

Lesen sie die antworten

#1 Armin Zingler
29/10/2009 - 23:16 | Warnen spam
Làsst sich auch reproduzieren:

Neues Winforms-Projekt anlegen, und dann:

Public Class Form1

Private Sub Form1_Load( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load

Dim tmr As New Timer

tmr.Interval = 500
AddHandler tmr.Tick, AddressOf OnTimerTick
tmr.Start()

End Sub

Private Sub Form1_Paint( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles Me.Paint

Dim watch = Stopwatch.StartNew

For i = 1 To 198
e.Graphics.DrawString("X", Font, Brushes.Black, 0, 0)
Next

watch.Stop()
Debug.Print(watch.Elapsed.ToString)

End Sub
Private Sub OnTimerTick(ByVal sender As Object, ByVal e As System.EventArgs)
Invalidate()
End Sub

End Class

Nach dem Start werden meistens fortlaufend 0,23s angezeigt. Manchmal werden sofort
nach dem Start 0,014s errreicht, manchmal erst nach Fokuswechsel (Alt+Tab), manchmal
nach Minimieren+Wiederherstellen, sicher aber nach Öffen des Fenstermenüs.

CPU-Frequenz ist konstant.

Armin

Ähnliche fragen