2012-04-07 9 views
1

文字列の代わりにStringBuilderを使用して、GDIを使用してイメージに文字列を描画することは、どうにかできますか? StringBuilderを受け入れるGraphics.DrawString()オーバーロードはありません。しかし、通常の文字列は場合によってはGC時間を大幅に増やすことができます(私の場合、CLRプロファイラによれば52%)。C#GDI + DrawString()with StringBuilder?

注:4.0以降のStringBuildersをサポートするXNA Frameworkは使用しないでください。

+7

StringBuilderは、文字列を "ビルド"するのに便利です。構築したら、stringbuilderとstringは同じパフォーマンスを持ちます。したがって、私はstringbuilderを渡すことがDrawString(全体の文字列を必要とする)のパフォーマンスを向上させる方法を見ていない...だから、私の答えは: 'StringBuilder'を使って文字列を構築し、' myStringBuilder.ToString() 'を'DrawString()' – digEmAll

+0

@digEmallに同意すると、あなたはstringbuilderとstringに関して、スティックの間違った部分を把握したように見えます。 –

+0

+1 for @digEmAll、StringBuilderでは、値が必要なときに.ToString()を呼び出すための文字列を生成しましょう。 –

答えて

0

私はいくつかの代替グラフィックスライブラリを使用せずに可能であるとは思わない。

.NET 4.0以降、StringBuildernot use a String class internallyになります(反射でもStringオブジェクトは抽出できません)。

myStringBuilder.ToString()を呼び出すとパフォーマンスが低下することは間違いありません。基本的には、呼び出されるたびにあなたの文字列のコピーを作成しています。しかし、Graphics.DrawString()を呼び出すコードでは、私はそれがボトルネックであるとは思わない。

+0

私の質問への答えは悲しいことに、「それは不可能です」という行に沿ったものです。 .ToString()自体はボトルネックではありません。しかし、それが割り当てるゴミはあります。古いシステムでは、これは.NETのGCがいくつかの目的には適していないため、fpsを完全になくします。ここでも、1つの.ToString()は存在しないかもしれませんが、50のようなものです。そのx60 /秒は3000xガベージ/秒です。 GCが〜1MBに達するとCollect()が実行され、参照が多すぎると分割された時間にあなたのfpsがなくなります。これがあまりにも多く発生した場合は、何があっても常にfpsがなくなります。 – Napoleon

+0

確かに私は文字列をあらかじめ割り当てることができます。しかし、はるかに常にそうではありません。これを回避するにはいくつかの方法がありますが、私は単純な組み込みの解決策または何かを望んでいました。 – Napoleon

+0

@Napoleon .NET GCがこの場合、アプリケーションのFPSに顕著な影響を与えるとは思わない。これらの一時的な文字列は確実に[世代0](http://msdn.microsoft.com/en-us/library/ee787088.aspx#generations)オブジェクトであり、ガベージコレクションの再配置および圧縮フェーズの対象ではありません。パフォーマンスの最大のヒットは、文字列を作成することになります(メモ:メモリの割り当て/割り当て解除にはコストはかかりません)。ガベージコレクションのマーキング段階では時間がかかりますが、これはFPSの差 –