views:

1219

answers:

4

We need to optimize the text rendering for a C# Windows Forms application displaying a large number of small strings in an irregular grid. At any time there can be well over 5000 cells visible that update 4 times per second. The font family and size is consistent across the cells, though the color may vary from cell to cell, as will bold/italic/plain.

I've seen conflicting information on the web about TextRenderer.DrawText vs. Graphics.DrawString being the fastest/best, which reduces to a GDI vs. GDI+ comparison at the Win32 level.

I've also seen radically different results on Windows XP vs. Windows Vista, but my main target is Windows XP. Articles promising great advances under WinFX and DirectX 10 aren't helpful here :-)

What's the best approach here? I'm not afraid of introducing a small C++/CLI layer and optimizing device context handling to squeeze out more performance, but I'd like some definitive advice about which direction to take.

EDIT: Thanks for the initial responses. I'll be trying a combination of background bitmap rendering and sticking with the GDI equivalent calls.

+1  A: 

GDI is faster at drawing in general that GDI+. I worked on a project that had to draw thousands of lines and text strings and switching from GDI+ to GDI made a significant performance improvement. That was using Windows XP so I cannot comment on Vista. I would also recommend using double buffering for your drawing to also improve performance. Create a compatible off screen bitmap and reuse that each time you need to draw.

Phil Wright
+3  A: 

5000+ text rendering is slow even with GDI, especially if you need scrolling. Create a separate rendering thread and notify the UI thread every 200 ms and bitblt the current results. It gives a smooth user experience.

+3  A: 

A Microsoft developer has posted a GDI vs. GDI+ Text Rendering Performance article on his blog which answers the raw speed question: on his system, GDI DrawText was about 6 times faster than GDI+ DrawString.

If you need to be a real speed demon, TextOut is faster than DrawText, but you'll have to take care of clipping and word-wrapping yourself. ExtTextOut supports clipping.

GDI rendering (TextRenderer) will be more consistent with other parts of Windows using GDI; GDI+ tries to be device-independent and so some spacing and emboldening are inconsistent. See the SQL Server 2005 Surface Area Configuration tool for an example of inconsistent rendering.

Mike Dimmick
The sample app in the blog link is the one I used when I saw the big difference between Vista and XP - on my Vista PC, GDI and GDI+ were equal, while on XP I see the 6x difference the author mentions... This is probably a Vista driver issue, but highlights some of the difficulties here - thanks!
Dave Moore
Historical note: ExtTextOut used to be the quickest way to draw a solid rectangle on some cards/drivers :)
Roger Lipscombe
A: 

Creating a C++/CLI interop class to do the drawing in native code will result in crazy-fast drawing. We've witnesses this and measured it.

If you're not up to doing that, we've found graphics.DrawString is just slightly faster than than TextRenderer.DrawText.

Judah Himango