Reducing time in C# Forms Control.set_Text(string) function

c#, timer, winforms

Solution

I ran into this issue myself, and ended up creating my own simple Label control.

.Net's Label control is a surprisingly complicated beast, and is therefore slower than we'd like.

You can make a class that inherits `Control`, call `SetStyle` in the constructor to make it double-buffered and user-painted, then override the `OnPaint` method to call `e.Graphics.DrawString` and draw the `Text` property. Finally, override `Text` or `TextChanged` and call `Invalidate`.

As long as you don't need AutoSize, this will be substantially faster than the standard Label control.

Here is my implementation: (Currently in use in production)

///<summary>A simple but extremely fast control.</summary>
///<remarks>Believe it or not, a regular label isn't fast enough, even double-buffered.</remarks>
class FastLabel : Control {
    public FastLabel() {
        SetStyle(ControlStyles.AllPaintingInWmPaint
               | ControlStyles.CacheText
               | ControlStyles.OptimizedDoubleBuffer
               | ControlStyles.ResizeRedraw
               | ControlStyles.UserPaint, true);
    }
    protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); Invalidate(); }
    protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); Invalidate(); }

    static readonly StringFormat format = new StringFormat {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Center
    };
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.DrawString(Text, Font, SystemBrushes.ControlText, ClientRectangle, format);
    }
}

If you don't want centering, you can get rid of, or change, the `StringFormat`.

Problem

Hoping for a quick answer (which SO seems to be pretty good for)... I just ran a performance analysis with VS2010 on my app, and it turns out that I'm spending about 20% of my time in the `Control.set_Text(string)` function, as I'm updating labels in quite a few places in my app. The window has a timer object (Forms timer, not Threading timer) that has a `timer1_Tick` callback, which updates one label every tick (to give a stop-watch sort of effect), and updates about 15 labels once each second. Does anyone have quick suggestions for how to reduce the amount of time spent updating text on a form, other than increasing the update interval? Are there other structures or functions I should be using?

Original source