Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cost of creating Font objects in .NET

Tags:

.net

fonts

In the application I'm developing , we use the DevExpress XtraGrid control, which has a RowCellStyle event that allows to customize the style of each cell. The event handlers for this event typically look like that :

private gridView1_RowCellStyle(object sender, RowCellStyleEventArgs e)
{
    if (/* Some condition */)
    {
        e.Appearance.Font = new Font(gridView1.Appearance.Font, FontStyle.Bold);
    }
}

This handler is called every time a cell is rendered, so it can create a large number of Font instances. So I'm wondering about the cost of doing that... I did a few experiments, and it seems that a new HFONT handle is created every time. Should I worry about it ? How big is the impact on resource usage ?

If it has a significant performance impact, shouldn't there be a FontCache class or something similar ?

Note : I know how to solve the problem (I just need to create the font once and reuse it every time), my question is really about the cost of creating many HFONT handles

like image 868
Thomas Levesque Avatar asked Nov 23 '09 20:11

Thomas Levesque


1 Answers

Test it; I get about double performance by reuse (in release, reuse = 3000ms, recreate = 4900ms)

using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
static class Program
{
    static void Main()
    {
        Button btn1, btn2;
        Form form = new Form
        {
            Controls = {
                (btn1 = new Button { Dock = DockStyle.Bottom, Text = "reuse" }),
                (btn2 = new Button { Dock = DockStyle.Bottom, Text = "recreate"})
            }
        };
        btn1.Click += delegate
        {
            var watch = Stopwatch.StartNew();
            using (var gfx = form.CreateGraphics())
            using (var font = new Font(SystemFonts.DefaultFont, FontStyle.Bold))
            {                
                gfx.Clear(SystemColors.Control);
                for (int i = 0; i < 10000; i++)
                {
                    gfx.DrawString("abc", font, SystemBrushes.ControlText, i % 103, i % 152);
                }
            }
            watch.Stop();
            form.Text = watch.ElapsedMilliseconds + "ms";
        };
        btn2.Click += delegate
        {
            var watch = Stopwatch.StartNew();
            using (var gfx = form.CreateGraphics())
            {
                gfx.Clear(SystemColors.Control);
                for (int i = 0; i < 10000; i++)
                {
                    using (var font = new Font(SystemFonts.DefaultFont, FontStyle.Bold))
                    {
                        gfx.DrawString("abc", font, SystemBrushes.ControlText, i % 103, i % 152);
                    }
                }
            }
            watch.Stop();
            form.Text = watch.ElapsedMilliseconds + "ms";
        };
        Application.Run(form);

    }
}
like image 123
Marc Gravell Avatar answered Sep 29 '22 08:09

Marc Gravell