2012-04-07 101 views
1

它以某種方式使用StringBuilder而不是字符串將使用GDI的字符串繪製到圖像上?沒有接受StringBuilder的Graphics.DrawString()重載。但是在某些情況下,常規字符串會顯着增加GC時間(根據CLR Profiler,在我的情況下爲52%)。C#GDI + DrawString()與StringBuilder?

注意:我不想使用從4.0開始支持StringBuilders的XNA Framework。

+7

StringBuilder對於「構建」一個字符串非常有用。一旦你建立它,stringbuilder和字符串具有相同的性能。因此,我沒有看到如何傳遞一個stringbuilder可以增加DrawString(需要整個字符串)的性能......所以,我的答案是:使用StringBuilder構建您的字符串,然後將myStringBuilder.ToString()傳遞給'DrawString()' – digEmAll 2012-04-07 10:52:13

+0

同意@digEmall,你似乎已經掌握了關於stringbuilder和string方面的錯誤的結束。 – 2012-04-07 11:19:44

+0

+1 for @digEmAll,StringBuilder讓我們生成字符串,讓您在需要值時調用.ToString()。 – 2012-04-07 17:11:36

回答

0

我不相信有可能沒有使用一些替代圖形庫。

由於.NET 4.0,StringBuilder確實not use a String class internally(即使有反射,您也無法提取String對象)。

你是對的,打電話myStringBuilder.ToString()將產生性能打擊;它實際上每次調用時都會創建一個字符串的副本。但在調用Graphics.DrawString()的代碼中,我只是沒有看到這是一個瓶頸。

+0

我的問題的答案可悲的是沿線「這是不可能的」。 .ToString()本身不是瓶頸。但它分配的垃圾是。在較舊的系統上,這將完全耗盡您的fps,因爲.NET中的GC不是......非常適合某些用途。同樣,可能沒有.ToString(),但是其中有50個。 x60 /秒是3000x垃圾/秒。當GC達到〜1MB時,我相信它會收集()並且如果有太多的參考文獻,它會在分裂時刻耗盡您的fps。如果這種情況發生得太多,無論發生什麼,它都會不斷消耗你的fps。 – Napoleon 2013-02-10 14:36:34

+0

當然有時我可以預先分配字符串。但目前並不總是如此。還有一些方法可以「繞過」,但我希望有一個簡單的內置解決方案或其他方法。 – Napoleon 2013-02-10 14:39:02

+0

@Napoleon在這種情況下,我認爲.NET GC不會對您的應用程序的FPS產生任何顯着影響。這些臨時字符串肯定是[第0代](http://msdn.microsoft.com/en-us/library/ee787088.aspx#generations)對象,並且不受垃圾回收的重定位和壓縮階段的限制。性能最大的命中將來自構造字符串(注意:內存分配/釋放應該不需要任何費用)。垃圾收集的標記階段會有一段時間的增加,但我懷疑這會使FPS分數的一小部分 – 2013-02-10 16:55:26