Если вам нужна грубая скорость, лучшим вариантом будет использование DirectX.Следующим лучшим вариантом, вероятно, будет использование GDI из C ++ и предоставление управляемого интерфейса для его вызова.Тогда, вероятно, p / вызвать GDI непосредственно из C #, и последним использовать GDI + в C #.Но в зависимости от того, что вы делаете, вы не увидите большой разницы.Многопоточность может не помочь вам, если вы ограничены скоростью, с которой видеокарта может работать с GDI +, но может быть полезной, если вы привязаны к процессору, решая, что рисовать.Если вы печатаете много изображений в последовательности, вы можете получить выгоду, выполнив предварительный расчет, рендеринг и печать «фаз» в отдельных потоках.
Тем не менее, есть ряд вещей, которые вы можете сделать, чтобы оптимизировать скорость перерисовки,как оптимизация, так и компромиссы, и эти подходы будут применяться к любой выбранной вами системе рендеринга.Действительно, большинство из них основано на тех же принципах, которые использовались при оптимизации кода.
Как можно минимизировать сумму, которую вы рисуете?
Во-первых, устраните ненужную работу.Подумайте о каждом элементе, который вы рисуете - действительно ли это необходимо?Зачастую более простой дизайн может выглядеть лучше при сохранении значительных усилий при рендеринге.Подумайте, можно ли заменить градуированную заливку на плоскую, или округленный прямоугольник будет выглядеть приемлемым как простой прямоугольник (и проверьте, дает ли это хоть какое-то преимущество в скорости на вашем оборудовании, прежде чем выбросить его!)
Бросьте вызов своим предположениям - например, требованию «высокого разрешения» - часто, если вы печатаете на чем-то, например, на принтере с красителем (это процесс, который вызывает небольшое цветовое кровотечение), или на принтере CMYK, который использует любую форму размываниядля смешивания цветов (у которых практическое разрешение намного ниже, чем у точки, которую принтер может разрешить), сглаженное изображение с относительно низким разрешением часто может давать столь же хороший результат, что и изображение со сверхвысоким разрешением.Если вы выводите на черно-белый принтер с разрешением 2400 точек на дюйм, вы все равно можете обнаружить, что приемлемо разрешение 1200 точек на дюйм или даже 600 точек на дюйм (при увеличении разрешения вы получаете все более низкие значения возврата, и большинство людей не заметят разницы между 600 точек на дюйм и 2400 точек на дюйм),Просто распечатайте несколько типичных примеров, используя разные исходные разрешения, чтобы увидеть, на что похожи результаты.Если вы можете уменьшить разрешение вдвое, вы можете визуализировать его в 4 раза быстрее.
Как правило, старайтесь не перерисовывать ту же область. Если вы хотите нарисовать черную рамку вокруг области, вы можете нарисовать белый прямоугольник внутричерный прямоугольник, но это означает заполнение всех пикселей в середине дважды.Вы можете улучшить производительность, нарисовав 4 черных прямоугольника вокруг, чтобы точно нарисовать рамку.И наоборот, если у вас много примитивов для рисования, можете ли вы уменьшить количество примитивов, которые вы рисуете?Например, если вы рисуете много полос, вы можете нарисовать чередующиеся прямоугольники разных цветов (= 2n прямоугольников) или вы можете залить весь фон одним цветом, а затем нарисовать только прямоугольники для второго цвета (= n + 1 прямоугольников).).Сокращение количества отдельных вызовов методов GDI + часто может обеспечить значительный выигрыш, особенно если у вас быстрое графическое оборудование.
Если вы рисуете какую-либо часть изображения более одного раза, рассмотрите возможность ее кэширования (визуализации в растровое изображение).и затем, при необходимости, копируем его до вашего окончательного изображения).Чем сложнее этот фрагмент изображения, тем более вероятно, что его кэширование окупится.Например, если у вас есть повторяющийся узор, такой как линейка, не рисуйте каждую маркировку линейки как отдельную линию - визуализируйте повторяющуюся часть линейки (например, 10 строк или 50), а затем перетяните эту отрисовку только несколько раз, чтобы нарисоватьпоследний правитель.
Точно так же избегайте выполнения ненужной работы (как, например, многие вызовы MeasureString для значений, которые можно предварительно рассчитать один раз или даже приблизить. Или, если вы шагаете по множеству значений Y, попробуйте сделать это, добавив смещение для каждогоитерация, а не повторное вычисление абсолютной позиции, используя каждый раз mutliples).
Попробуйте «пакетное» рисование, чтобы минимизировать количество необходимых изменений состояния и / или вызовов метода рисования, которые необходимы - например, нарисовать все элементы, которые находятся водин цвет / текстура / кисть, прежде чем перейти к следующему цвету.Используйте «пакетные» вызовы рендеринга (например, рисуйте полилинейный примитив один раз, а не вызывайте DrawLine 100 раз).
Если вы выполняете какие-либо операции с пикселем, то обычно гораздо быстрее получить буфер необработанного изображенияи манипулировать им напрямую, чем вызывать методы GetPixel / SetPixel.
И, как вы уже упоминали, вы можете отключить дорогостоящие операции, такие как сглаживание и сглаживание шрифтов, которые не принесут никакой пользы.в вашем конкретном случае.
И, конечно же, посмотрите на код, который вы рендерите, - профилируйте его и примените обычные оптимизации, чтобы помочь ему эффективно работать.
Наконец, наступает моментгде вы должны подумать о том, может ли обновление оборудования стать дешевым и эффективным решением - если у вас медленный ПК и видеокарта младшего класса, вы можете получить значительный выигрыш, просто купив новый ПК с лучшей видеокартой в нем.,Или, если образы огромные, вы можете обнаружить, что на пару ГБ больше оперативной памяти устраняет накладные расходы на подкачку виртуальной памяти.Это может звучать дорого, но наступает момент, когда стоимость / выгода от нового оборудования лучше, чем тратить больше денег на дополнительную работу по оптимизации (и их постоянно уменьшающийся доход).