Cache the instance of Graphics
and Font
objects so that you don't need to create them each time you measure the length of string. I've created a small test to see which part takes most of the time:
private static void Main()
{
Stopwatch stopwatch = Stopwatch.StartNew();
stopwatch.Restart();
for (int i = 0; i < 1000000; i++)
{
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
{
var size = g.MeasureString("asdasdf", new System.Drawing.Font("Arial", 14)).Width;
}
}
Console.WriteLine("Current solution - create a new Graphics per measure: {0} milliseconds", stopwatch.ElapsedMilliseconds);
stopwatch.Restart();
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
{
for (int i = 0; i < 1000000; i++)
{
var size = g.MeasureString("asdasdf", new System.Drawing.Font("Arial", 14)).Width;
}
}
Console.WriteLine("Measure the string with Graphics cached: {0} milliseconds", stopwatch.ElapsedMilliseconds);
stopwatch.Restart();
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
using (var font = new System.Drawing.Font("Arial", 14))
{
for (int i = 0; i < 1000000; i++)
{
var size = g.MeasureString("asdasdf", font).Width;
}
}
Console.WriteLine("Measure the string with Graphics and font cached: {0} milliseconds", stopwatch.ElapsedMilliseconds);
}
Results on my computer are:
Current solution - create a new Graphics per measure: 26864 milliseconds
Measure the string with Graphics cached: 6588 milliseconds
Measure the string with Graphics and font cached: 803 milliseconds
So by caching Graphics
you'll reduce the time consumption by 75%, and by caching both Font
and Graphics
you get a nice 33.5X performance boost :).
…
, and not three dots. You might also be interested in gist.github.com/4250125 \$\endgroup\$