Стоимость создания Шрифта возражает в.NET

Был ряд экранной демонстрации приблизительно один год назад на Полиморфном Подкасте, который сделал довольно хорошую вводную пошаговую демонстрацию реализации MVP в ASP.NET. Реализованный этот путь, модульные тесты встают на свое место намного более естественно.

http://polymorphicpodcast.com/shows/mv-patterns/

6
задан tshepang 16 May 2014 в 18:07
поделиться

3 ответа

Протестируйте; Я получаю двойную производительность за счет повторного использования (в выпуске повторное использование = 3000 мс, воссоздание = 4900 мс)

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);

    }
}
6
ответ дан 10 December 2019 в 00:39
поделиться

Шрифт реализует IDisposable - вы должны убедиться, что вы вызываете Dispose, когда закончите с ним.

Это неуправляемый ресурс, поэтому возможно, что ОС в конечном итоге исчерпает ресурсы, чтобы предложить вам дополнительные объекты.

Проверьте количество дескрипторов GDI в TaskManager, чтобы убедиться, что оно постоянно увеличивается.

2
ответ дан 10 December 2019 в 00:39
поделиться

Повторное использование почти всегда быстрее, чем по требованию, но ваши возможности по повторному использованию или кэшированию объектов Font могут различаться.

Если вы повторно используете объекты Font и связываете отдельные объекты Font с каждым элементом управления, вы увеличите шанс превышения лимита ручки gdi. Когда это происходит, это повредит всем приложениям, используемым данным пользователем.

В идеале, вы должны кэшировать объекты Font на уровне приложения / процесса и только минимальный набор, который необходим (возможно, не более дюжины). Кроме того, кеширование небольшого общего набора шрифтов и других объектов GDI позволяет лучше справляться с такими сложными сообщениями, как WM_SETTINGCHANGE. В вашем примере вы изменяете значения по умолчанию, и вы можете столкнуться с ошибками рисования, когда пользователь изменяет схемы или шрифт отображения по умолчанию в окнах. Во время WM_SETTINGCHANGE, вы могли бы рассмотреть возможность выпуска кэшированных копий и инициализации или подготовки новых наборов объектов шрифтов.

WM_SETTINGCHANGE (Windows) @ MSDN

Если вам необходимо иметь сотни различных шрифтов (или других объектов gdi), вам следует не кешировать шрифты и создавать только то, что вам нужно, по запросу. Это не способствует производительности, но поможет вашему приложению сосуществовать с другими приложениями, открытыми пользователем. Хранение сотен объектов GDI значительно увеличит вероятность того, что пользователь столкнется с ограничением дескриптора GDI. Однако кэш на основе подсчета ссылок может предоставить здесь компромисс, который лучше всего подходит для вас, храня бумажные копии только наиболее часто используемых вариантов.

Наконец, как упомянул Мэтт Брекон, используйте IDisposable для всех Объекты GDI, для которых он доступен. Это поможет вам избежать утечек ручки gdi.

2
ответ дан 10 December 2019 в 00:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: