Я догадался, что вы делаете это для отображения части изображения на экране, потому что вы упомянули UIImageView
. А проблемы оптимизации всегда нужно конкретно определять.
Доверяйте Apple для обычного пользовательского интерфейса
На самом деле, UIImageView
с clipsToBounds
- это один из самых быстрых / простых способов архивирования вашей цели, если ваша цель - просто вырезать прямоугольную область изображения (не слишком большую). Также вам не нужно отправлять setNeedsDisplay
сообщение.
Или вы можете попробовать поместить UIImageView
внутри пустого UIView
и установить отсечение в представлении контейнера. С помощью этой техники вы можете свободно трансформировать изображение, установив свойство transform
в 2D (масштабирование, вращение, перемещение).
Если вам нужно 3D-преобразование, вы все равно можете использовать CALayer
со свойством masksToBounds
, но использование CALayer
даст вам очень небольшую дополнительную производительность, обычно незначительную.
В любом случае, вам нужно знать все детали низкого уровня, чтобы правильно их использовать для оптимизации.
Почему это один из самых быстрых способов?
UIView
- это просто тонкий слой поверх CALayer
, который реализован поверх OpenGL , который является практически прямым интерфейсом к GPU . Это означает, что UIKit ускоряется GPU.
Так что, если вы используете их правильно (я имею в виду, в рамках заданных ограничений), он будет работать так же, как и простая реализация OpenGL
. Если вы используете для показа всего несколько изображений, вы получите приемлемую производительность с реализацией UIView
, поскольку она может получить полное ускорение базового OpenGL (что означает ускорение графического процессора).
В любом случае, если вам нужна экстремальная оптимизация для сотен анимированных спрайтов с тонко настроенными пиксельными шейдерами, как в игровом приложении, вы должны использовать OpenGL напрямую, потому что CALayer
не имеет много параметров для оптимизации на более низких уровнях. В любом случае, по крайней мере для оптимизации пользовательского интерфейса, невероятно сложно быть лучше, чем Apple.
Почему ваш метод медленнее, чем UIImageView
?
Что вам следует знать, так это ускорение GPU. На всех современных компьютерах высокая производительность графики достигается только с помощью графического процессора. Затем дело в том, реализован ли используемый вами метод поверх графического процессора или нет.
IMO, CGImage
методы рисования не реализованы на GPU.
Я думаю, что прочитал упоминание об этом в документации Apple, но я не могу вспомнить, где. Так что я не уверен в этом. В любом случае, я считаю, что CGImage
реализован в CPU, потому что
- Его API выглядит так, как будто он предназначен для ЦП, например, интерфейс редактирования растровых изображений и рисования текста. Они не очень хорошо подходят для интерфейса GPU.
- Интерфейс растрового контекста обеспечивает прямой доступ к памяти. Это означает, что его внутреннее хранилище находится в памяти процессора. Может быть, несколько отличается в архитектуре унифицированной памяти (а также с Metal API), но в любом случае первоначальное намерение разработки
CGImage
должно быть для CPU.
- Многие недавно выпустили другие API Apple, явно упоминающие ускорение графического процессора. Это означает, что их старые API не были. Если нет особого упоминания, по умолчанию это обычно делается в CPU.
Так что, похоже, это делается в CPU. Графические операции, выполняемые в CPU, выполняются намного медленнее, чем в GPU.
Простое вырезание изображения и наложение слоев изображения - это очень простая и дешевая операция для GPU (по сравнению с CPU), поэтому вы можете ожидать, что библиотека UIKit будет использовать это, потому что весь UIKit реализован поверх OpenGL.
Об ограничениях
Поскольку оптимизация - это своего рода работа в области микроуправления, очень важны конкретные цифры и небольшие факты.Что такое среднего размера ?OpenGL на iOS обычно ограничивает максимальный размер текстуры до 1024x1024 пикселей (возможно, больше в последних выпусках).Если ваше изображение больше этого, оно не будет работать, или производительность будет сильно снижена (я думаю, что UIImageView оптимизирован для изображений в определенных пределах).
Если вам нужно отображать огромные изображения с отсечкой, у вас естьиспользовать другую оптимизацию, такую как CATiledLayer
, и это совсем другая история.
И не переходите на OpenGL, если вы не хотите знать все детали OpenGL.Требуется полное понимание низкоуровневой графики и как минимум в 100 раз больше кода.
О каком-то будущем
Хотя это не очень вероятно, но CGImage
вещи (иливсе остальное) не нужно застрять только в процессоре.Не забудьте проверить базовую технологию используемого вами API.Тем не менее, компоненты GPU сильно отличаются от CPU, тогда как парни из API обычно явно и ясно упоминают о них.