2012-04-07 17 views
1

Es ist irgendwie möglich, eine Zeichenkette mit dem GDI auf ein Bild mit einem StringBuilder anstelle einer Zeichenkette zu zeichnen? Es gibt keine Graphics.DrawString() - Überladung, die einen StringBuilder akzeptiert. Aber eine reguläre Saite kann in manchen Fällen die GC-Zeit dramatisch erhöhen (in meinem Fall 52% laut CLR Profiler).C# GDI + DrawString() mit StringBuilder?

Hinweis: Ich möchte nicht das XNA Framework, das StringBuilders ab 4.0 unterstützt.

+7

StringBuilder ist nützlich, um eine Zeichenfolge zu "bauen". Sobald Sie es erstellt haben, haben Stringbuilder und String die gleiche Leistung. Daher kann ich nicht sehen, wie die Übergabe eines Zeichenfolgers die Leistung von DrawString (die den ganzen String benötigt) erhöht ... Also lautet meine Antwort: Erzeuge deinen String mit 'StringBuilder' und gebe 'myStringBuilder.ToString()' an 'DrawString()' – digEmAll

+0

Stimmen Sie mit @digEmall überein, Sie scheinen das falsche Ende des Sticks zu haben, in Bezug auf Stringbuilder und String. –

+0

+1 für @digEmAll, StringBuilder lassen Sie die Zeichenkette generieren, so dass Sie .ToString() aufrufen können, wenn Sie den Wert benötigen. –

Antwort

0

Ich glaube nicht, dass es möglich ist, ohne eine alternative Grafikbibliothek zu verwenden.

Seit .NET 4.0, StringBuilder tut not use a String class internally (sogar mit Reflexion können Sie ein String Objekt nicht extrahieren).

Sie haben recht, dass der Aufruf myStringBuilder.ToString() einen Leistungseinbruch verursacht; Es macht im Wesentlichen eine Kopie der Zeichenfolge jedes Mal, wenn es aufgerufen wird. Aber im Code, der Graphics.DrawString() aufruft, sehe ich das nicht als Engpass.

+0

Die Antwort auf meine Frage ist leider etwas in die Richtung "es ist nicht möglich". Die .ToString() selbst ist nicht der Flaschenhals. Aber der Müll, den es zuweist, ist. Bei älteren Systemen wird dies Ihre fps komplett entleeren, weil der GC in .NET nicht so ... für einige Zwecke großartig ist. Auch hier gibt es vielleicht keinen .ToString(), aber 50 davon. Das x60/Sekunde ist 3000x Müll/Sekunde. Wenn der GC ~ 1MB erreicht, glaube ich, dass es Collect() ist und wenn es zu viele Referenzen gibt, wird es für einen gespaltenen Moment deine fps drainieren. Wenn dies zu viel passiert, wird es ständig Ihre fps entleeren, egal was passiert. – Napoleon

+0

Sicher kann ich manchmal die Zeichenfolge vorbelegen. Aber bei weitem nicht immer. Es gibt auch einige Möglichkeiten, um das zu "hacken", aber ich habe auf eine einfache Build-In-Lösung gehofft oder so. – Napoleon

+0

@ Napoleon Ich glaube nicht, dass der .NET GC in diesem Fall spürbare Auswirkungen auf den FPS Ihrer Anwendung haben wird. Diese temporären Strings sind sicherlich [generation 0] (http://msdn.microsoft.com/en-us/library/ee787088.aspx#generations) -Objekte und unterliegen nicht den Phasen des Verschiebens und Komprimierens von Garbage Collection. Der größte Leistungseinbruch wird durch den Aufbau der Zeichenkette erreicht (Anmerkung: die Speicherzuweisung/Freigabe sollte nichts kosten). Es wird eine Zeitsteigerung in der Markierungsphase der Speicherbereinigung geben, aber ich bezweifle, dass dies sogar einen Bruchteil eines FPS ausmachen wird –