1

It it somehow possible to draw a string using the GDI onto an image using a StringBuilder instead of a string? There is no Graphics.DrawString() overload that accepts a StringBuilder. But a regular string can in some cases dramatically increase the GC time (in my case 52% according to the CLR Profiler).

Note: I DON'T want to use the XNA Framework which supports StringBuilders as of 4.0.

Napoleon
  • 1,072
  • 5
  • 17
  • 31
  • 7
    StringBuilder is useful to "build" a string. Once you have built it, stringbuilder and string have the same performance. Hence, I don't see how passing a stringbuilder can increase the performance of DrawString (that needs the whole string)... So, my answer is: build your string using `StringBuilder` then pass `myStringBuilder.ToString()` to `DrawString()` – digEmAll Apr 07 '12 at 10:52
  • Agree with @digEmall, you appear to have grasped the wrong end of the stick, in terms of stringbuilder and string. – Tony Hopkinson Apr 07 '12 at 11:19
  • +1 for @digEmAll, StringBuilder let's you generate the string leaving you to call .ToString() when you need the value. – Jamie Keeling Apr 07 '12 at 17:11
  • 1
    @digEmAll: It wouldn't make `DrawString` any faster; it would make the program faster overall because the GC would have less garbage to collect because a single `StringBuilder` can be used to draw all your strings, while each string requires a different `string`. – Gabe Apr 07 '12 at 17:14
  • @Gabe: yes, in that sense it can be useful. Even if, in a certain way, it means sacrificing the safeness given by the string-immutability. – digEmAll Apr 07 '12 at 18:18
  • Doesn't the StringBuilder.ToString() itself cost a lot of allocation? When I run the CLR profiler the .ToString() (in my case it runs on ~30fps) creates a lot of allocations on the heap because it is performed 30 times/second for each .ToString() call. I also read something about it here: http://www.gavpugh.com/2010/03/23/xnac-stringbuilder-to-string-with-no-garbage/ But I also read on the XNA forums that StringBuilder.Insert() for example also internally calls .ToString(). See here:http://forums.create.msdn.com/forums/p/16395/132030.aspx – Napoleon Apr 23 '12 at 12:22

1 Answers1

0

I don't believe it is possible without using some alternative graphics library.

Since .NET 4.0, StringBuilder does not use a String class internally (even with reflection you cannot extract a String object).

You are right that calling myStringBuilder.ToString() will incur a performance hit; it is essentially making a copy of your string each time it is called. But in code that calls Graphics.DrawString(), I just don't see that being a bottleneck.

Community
  • 1
  • 1
Mr. Smith
  • 4,288
  • 7
  • 40
  • 82
  • The answer to my question is sadly something along the lines "it's not possible". The .ToString() itself is not the bottleneck. But the garbage that it allocates is. On older systems this will completely drain your fps because the GC in .NET is not... that great for some purposes. Again, there might not be one .ToString() but like 50 of them. That x60/second is 3000x garbage/second. When the GC reaches ~1MB I believe it will Collect() and if there are too many references it will drain your fps for a split moment. If this happens too much it will constantly drain your fps no matter what. – Napoleon Feb 10 '13 at 14:36
  • Sure sometimes I can pre-allocate the string. But by far not always. there are also some ways to 'hack' around this but I was hoping for a simple build-in solution or something. – Napoleon Feb 10 '13 at 14:39
  • @Napoleon I don't think the .NET GC is going to have any noticeable impact on the FPS of your application in this case. These temporary strings will surely be [generation 0](http://msdn.microsoft.com/en-us/library/ee787088.aspx#generations) objects, and not subject to the relocating and compacting phases of garbage collection. The largest performance hit will come from constructing the string (note: the memory allocation/deallocation should cost nothing). There will be a time increase in the marking phase of garbage collection, but I doubt that that will make even a fraction of an FPS differen – Mr. Smith Feb 10 '13 at 16:55