How can I make this code (that is usually in a loop) faster and efficiently?
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 &lt; 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 &lt; 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 &lt; 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 :).