Практика оптимизации анимации клиента iOS
Практика оптимизации анимации клиента iOS

GIF и Animated WebP Это самый популярный формат анимации в Интернете. Но в iOS В разработке, родной UIImage не поддерживает напрямую GIF а также Animated WebP отображать, Поэтому существуют различные отличные сторонние решения с открытым исходным кодом, Например SDWebImage а также YYImage ждать. Эта статья будет основана на QQ музыка iOS Основываясь на практике оптимизации анимации в конце, Представить различные решения и идеи плюсы и минусы, И предоставить план оптимизации.

1. Проблемы с отображением конечной анимации и результатами оптимизации.

В течение долгого времени некоторые модели были склонны к сбоям при просмотре изображений и текстовых потоков Q Sound, а также существует множество отчетов о сбоях, связанных с анимацией в других службах терминала.

Причина сбоя в том, что при загрузке изображений в терминал они заранее декодируются в асинхронном потоке. Декодирование большого количества кадров анимации за короткий промежуток времени будет быстро расходовать доступную память, что напрямую приводит к сбою. Сбой NSMallocException (не удалось увеличить буфер) перед запуском системного уведомления MemoryWarning, также легко вызвать OOM. Через два месяца мы запустили решение покадрового декодирования анимированных изображений в оттенках серого и инкапсулировали его как универсальный компонент загрузки изображений QMAnimatedImageView. Оптимизация принесла следующие улучшения:

  1. Решите проблему частых сбоев выставочной анимации,включать OOM / NSMallocException / CPU нагрузкаслишком высокийждать.
  2. существовать Когда каждый кадр декодируется, оптимизациядо и после Первый кадр загруженпродолжительностьплоский.
  3. картина Память Скорость попадания определяется выражением 65% подняться до 76%.
  4. По сравнению с основными решениями с открытым исходным кодом YYAnimatedImageView а также SDAnimatedImageView,  CPU Берите меньше,Памятьиспользоватьменьше, И у него лучше беглость.
  5. Инкапсулировано в универсальное решение для загрузки изображений, поддержка повторного использования анимации и статических изображений, поддерживать GIF/Animated WebP/APNG Формат анимации.

2. iOS Как отображать анимацию

Сначала мы познакомим вас с некоторыми общими причинами. отображать анимацию:

2.1 Используйте ImageIO.framework для отображения анимированных изображений

Как упоминалось выше, UIImage Он не поддерживает напрямую отображение анимированных изображений. Используйте напрямую [UIImage imageNamed:] а также [UIImage imageWithData:] Метод загрузки файлов анимации, Вы получите только статичное изображение. Используйте родной API выставка GIF Нужно использовать ImageIO.framework Источник data Разобрать каждый кадр в Прошло одновременно UIImageView из animationImages Свойства для достижения анимации изпод поддержки. Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
    // 1. производить CGImageSourceRef    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    int count = CGImageSourceGetCount(source);    NSMutableArray *images = [NSMutableArray array];    for (int i = 0; i < count; i++)    {        // 2. Траверс для получения каждого кадра        CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);        [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];        // 3. Обратите внимание на выпуск, Вы можете добавить один здесь autorelease        CGImageRelease(image);    }    // CGImageSourceRef Также выпустите    CFRelease(source);
    UIImageView *imageView = [[UIImageView alloc] init];    // 4. проходить animationImages настраиватьанимация    imageView.animationImages = images;    // 5. Обработка получения каждого кадра немного сложна, Сначала следите за каждым кадром 100ms Бар    imageView.animationDuration = 0.1 * count;    // 6. Запустить анимацию    [imageView startAnimating];

2.2 FLAnimatedImage

FLAnimatedImage да FlipBoard Ранний открытый исходный код библиотеки загрузки анимации, Идея реализации представляет собой типичную модель потребитель-производитель. 

  • FLAnimatedImageView дапотребитель, проходить CADisplayerLink Тайминг выставки текущего кадра;
  • FLAnimatedImage дапродюсер, существоватьасинхронный потокпроходить CGImageSourceCreateImageAtIndex Получите кадр и раскодируйте его, Также кэшируйте данные кадра; 
  • существовать CADisplayerLink При срабатывании выставка соответствует кадру. Но библиотека да все-таки слишком старая. Производительность не так хороша, как YYAnimatedImageView, Справки пока нет.

2.3 YYAnimatedImageView реализация и недостатки

YYAnimatedImageView внедрение и FLAnimatedImage похожий: 

  • использовать YYImageCoder Чтобы выполнить анализ кадров анимации, поддерживают различные форматы;
  • существовать YYAnimatedImageView Mediumuse семафор, оптимизация считывания кадров Асинхронное декодирование, ииспользовать NSDictionary сделать буферизацию кадров,
  • использоватьCADisplayLink Чтобы сделать анимацию отображаемой, Также добавьте задачу декодирования кадров.

Реализация YYImageDecoder

YYImageDecoder Отвечает за анализ изображений или кадров анимации в YYImageFrame объект, поддерживать APNG а также WebP, Краткий процесс декодирования выглядит следующим образом: 

  1. YYImageDecoder Инициализация определит тип изображения, и生становиться每一рамкаизинформация.
    1. Общие фотографиииспользовать [self _updateSourceImageIO] декодирование.
      1. инициализация CGImageSourceRef, зачитать frameCount,
      2. Перебирать каждый кадр, Получите ширину и высоту кадра/продолжительность/направление и другую информацию.
    2. WebP использовать [self _updateSourceWebP]декодирование, Положитесь на WebP.framework  Соответствующая информация была проанализирована.
    3. APNG использовать [self _updateSourceAPNG] декодирование.
      1. использовать _updateSourceImageIO Постройте первый кадр,
      2. Позвонил снова yy_png_info_create Метод анализируется из исходного файла APNG Связанные параметры.
  2. использовать frameAtIndex:decodeForDisplay: Получите соответствующий кадр.
    1. первыйиспользовать_newUnblendedImageAtIndex:extendToCanvas:decoded:Получить кадриз CGImageRef, Этот шаг также даиспользовать CGImageSourceCreateImageAtIndex Получите соответствующий кадр,
    2. Затемиспользовать YYCGImageCreateDecodedCopy()декодирование, 默认использовать CGContextDrawImage & CGBitmapContextCreateImage Это набор методов для декодирования.

Следующее декодирование YYAnimatedImageView и процесс фотосъемки:

YYAnimatedImageView не может удовлетворить потребности бизнеса

YYAnimatedImageView существуют одновременно выставка Большое количество анимационных сцен не может удовлетворить потребности бизнеса:

  1. YYAnimatedImageView использовать NSDictionary для управления буфером кадров, iOS Система ответит, когда памяти не хватает NSDictionary сделать сжатие, Из ипроизводить дополнительно из CPU потребление, в соответствии с WWDC iOS Memory Deep Как сказано в Dive[1],Следует попытатьсяиспользовать NSCache Делать кэширование; 
  2. View Свяжите фреймбуфер напрямую, существуют быстро слайд сцены, View Постоянно загружается новая анимация, Декодированный кадр будет выпущен напрямую, Перекодировать новые изображения из каждого кадра,привести к CPU нагрузкаслишком высокий, существования Легко быстро проводить пальцем вперед и назад в потоке изображений и текста.

2.4 Знакомство с использованием каждой версии SDWebImage

Выше сказано, что обе сторонние библиотеки загружают файлы локально,Не прямойподдерживатьсуществоватьзагрузка линии, в YYAnimatedImageView Сотрудничать YYWebImage Онлайн-загрузка может быть легко реализована, Но опыт даиспользовать не так хорош, как SDWebImage. Кратко представим это с помощью блок-схемы. SDWebImage3 процесс загрузки изображения, Последующие версии в основном продолжили эту идею:

  • SDWebImage Он также был интегрирован на ранней стадии FLAnimatedImageView существуют для загрузки линии GIF, позжепроходить[UIImage animatedImageWithImages: duration:] Прямой анализ GIF для _UIAnimatedImage (UIImage изPrivate подкласс)
  • SDWebImage4 Рассчитаны кадрыпродолжительностьизнаибольший общий делительдля пакетного добавления одного и того же кадра, Чтобы добиться разных кадров, разной продолжительность выставки, Решите проблему искажения анимации.
  • SDWebImage5 представлятьSDAnimatedImageView, То же, что SDWebImage Простой интерфейс, может быть напрямуюиспользоватьSDWebImageMatchAnimatedImageClass options загрузить анимацию, Код выглядит следующим образом:
Язык кода:javascript
копировать
SDAnimatedImageView *imageView = [SDAnimatedImageView new];[imageView sd_setImageWithURL:[NSURL URLWithString:url]             placeholderImage:nil                      options:SDWebImageMatchAnimatedImageClass];

Да Обратите внимание наизда, С помощью вышеуказанного метода Изображение загружается в кэш памяти, 那么картинаиз ПримердаодинSDAnimatedImageобъект, Используйте другие UIImageView Загрузите url попасть в кеш памяти, На странице выставкисуществовать только одно статичное изображение.

SDAnimatedImageView проходить SDAnimatedImagePlayer Осуществить анимационную извыставку.

  1. 调использоватьsetImage:время встречиинициализацияновыйиз player.
  2. использовать SDDisplayLink (для CADisplayLink из упаковки, в то же времяподдерживать iOS/tvOS/macOS/watchOS) Зайдите на выставку соответствующего кадра.
  3. использоватьNSOperationQueueсуществовать背景线程进行декодирование, Затем存储существоватьplayerизframeBufferсредняя работадлякэш. Подводя итог, идеи заключаются в следующем: YYAnimatedImageView почти.

3. Идеи и проблемы загрузки анимации на Qyin iOS

我们项глаз中картина加载дас раннегоиз SDWebImage эволюционировал из Позже, по мере развития бизнеса, Добавлена ​​логика, такая как асинхронное декодирование/загрузка статистики/переключение на внутренние сетевые компоненты.

При загрузке анимированных изображений с помощью этого решения возникают три проблемы:

  1. Его можно отобразить только тогда, когда загружены все изображения кадра. особенныйдасуществовать ДелатьАсинхронное декодированиеизкогда, встречапривести кгифкаПервый кадр загруженпродолжительностьдольше.
  2. Разные кадры, выставкапродолжительность одинаковая,делатьИскажение движущегося изображения. (наибольший общий делительРешение можно решить)
  3. существования Фоновый поток анализирует все кадры, В это время, если кадр не декодируется, это приведет к задержке. Да ДелатьАсинхронное декодирование, Маленький Памятьиз机型встречапрямойВсплеск памятипривести ккрах, Поэтому существование можно включить только в оттенках серого онлайн.

Исходя из вышеперечисленных проблем, должно бытьЗагружать покадрово思路应использовать到端内, Когда анимация загружается в память, Декодируйте только первый кадр из двоичных данных; затем в CADisplayLink При срабатывании проанализировать требуемый в данный момент кадр фотоиз, При этом рационально используйте кадровый буфер, избегайте вышеперечисленного YYAnimatedImageView Непрерывная загрузка анимации приводит к кизвопрос.

4. Практика оптимизации загрузки анимации на Qyin iOS

Q звук iOS Процесс асинхронной загрузки изображений терминала аналогичен описанному выше. SDWebImage Процесс загрузки аналогичен Процесс декодирования будет немного отличаться, Q Блок-схема декодирования звукового изображения выглядит следующим образом:

Ниже приведены вопросы о депонировании существования по одному:

4.1 При декодировании каждого кадра первый кадр загружается слишком медленно

Как реализовать анимированную графику из Загрузить покадрово на основе платформы асинхронной загрузки?

4.1.1 Решение для покадровой загрузки анимированных изображений

в настоящий моментизкартина加载流程из Основные болевые точкида, Анимация напрямую проходит и декодирует каждый кадр. Взять на себя многое в одно мгновение CPU а также Память.

Идеи оптимизации следующие:

  1. существуют инкапсулировать анимацию перед ее декодированием QMAnimatedWebImage(UIImage Подкласс)и Декодировать только первый кадр,
  2.  сдавать QMAnimatedImageView(UIImageView из Подкласс)прямойвыставка,
  3. существовать QMAnimatedImageView Добавить CADisplayLink Тайминг выставки соответствующего кадра,
  4. Запустить очередь задач,Асинхронное декодирование Вскоревыставкаизрамка, 放существовать QMAnimatedImageView из области кэша. Таким образом, компонент динамического изображения может быть загружен асинхронно и декодирован покадрово. На картинке ниже показан процесс декодирования анимации, красное слово да Загрузить покадровоиз Трансформация.

4.1.2 Затраты времени на первый кадр

После завершения трансформации, Необходимо проверить Загрузить покадровопланданетвстречасуществовать Первый кадр Улучшения были сделаны в разделе «Загружено».

По данным онлайн-статистики, Для оптимизации декодирования предыдущих данных, а такжеоптимизация покадрового декодирования трех схем, Средние данные загрузки первого кадра следующие:

По сравнению с расшифровкой всего заранее, Покадровое декодирование из Первый кадр требует времяуменьшать половину; В период оттенков серого Среднее время, необходимое для загрузки первого кадра анимации, равно 25ms колебаться вверх и вниз, Покадровое декодирование не оказывает очевидного влияния на общие данные.

4.2 Искажение движущегося изображенияизвопрос

потому что QMAnimatedImageView дапроходить CADisplayLink управлять кадрами, отображать, существующая выставка будет показывать следующий кадр только тогда, когда временной интервал от предыдущего кадра превысит продолжительность кадра, Натуральное решение движущегося изображенияизвопрос, Он также может избежать таких вещей, как SDWebImage4 Считайте каждый кадр так общий делитель.

4.3 Проблема взрыва памяти, вызванная декодированием кадров

заранее Асинхронный декодирование изображений для общих идей и оптимизация, После декодирования CGRasterData кэшируется в памяти, Подождите, пока основной поток отрендерит изображение и перестанет его декодировать. 以解决系统неявное декодированиепривести киз Катон.

Но в анимированной сцене, Непрерывное декодирование анимации быстро потребляет память. Недостаток памяти приводит к снижению частоты попадания в кэш анимации. Новая анимация запускает декодирование, которое будет дополнительно потреблять CPU, MemoryWarning Авария произошла до срабатывания; CPU и Память бегут друг против друга, Сложно оптимизировать.

YYAnimatedImageView Декодировать только первый кадр, И сохраните анимацию NSData, Декодирование кадров в фоновом потоке. Но даже в этом случае, При постоянной загрузке анимации На слабых машинах по-прежнему существуют проблемы с производительностью. существующие пользователи быстро проводят пальцем по экрану или обновляют данные за пределами сцены, YYAnimatedImageView Все данные кадра предыдущего изображения будут удалены. На следующей выставке эта картинка будет снова расшифрована с начала, вызвать дополнительные CPU потребление, Продолжайте выполнять следующие оптимизации здесь.

4.3.1 Кэш кадров NSDictionary изменен на NSCache

YYAnimatedImageView использовать NSDictionary кэшировать декодированные кадры, Да iOS Система ответит, когда памяти не хватает NSDictionary сделать сжатие, Из ипроизводить дополнительно из CPU потребление, и освобождение фреймбуфера зависит от MemoryWarning уведомить. и NSCache Больше подходит для данных с большими издержками кэша. И потокобезопасность, Система автоматически соответствии с Памятьиспользовать Состояниеа такжеcost Удалить кеш напрямую, В этой оптимизации Декодируйте кадры с помощью NSCache кэшировать.

4.3.2 Отмените привязку просмотра и кэша кадров для оптимизации проблемы высокой нагрузки на процессор при быстром скольжении сцен.

YYAnimatedImageView Буфер кадра да находится непосредственно View держись из, привести к View При переключении изображений Буфер кадра был ранее освобожден, существовать Cell В сценариях мультиплексирования YYAnimatedImageView Буду продолжать разбирать картинки к CPU Расход слишком высокий.

В этой оптимизации QMAnimatedImageView Не хранит фреймбуфер напрямую, идапроходить QMAnimatedWebImage хранить фреймбуфер, Если анимация SDImageCache освобожденный из памяти, QMAnimatedWebImage Это также очистит буфер кадров, существовать Cell повторное использование сцен, Пока буфер кадра декодирован, декодирование не будет выполняться повторно. Пока анимация не освобождена из кэша памяти, Буфер кадра не будет очищен.

4.3.3 субдискретизация, Время для космоса

существоватьдействительный В разработке, Часто возникают ситуации, когда размер изображения значительно превышает площадь отображения. Потеря памяти при анимации ужасна. В этом случае можно использовать понижающую дискретизацию. Downsampling Технология снижения После декодирования Память.

Как и подвеска ниже, Даже если согласно 3X Экрану нужно только 175*105 размера достаточно, Да Проблемаизкартина却да 500*300. существуетпрохождение онлайн-мониторинга для проверки этих case в то же время, Включение пониженной дискретизации может мгновенно решить проблему потребления Память.

Справочник по понижению разрешения WWDC Image and Graphics Best Practices[2] Просто предоставьте реализацию кода:

Язык кода:javascript
копировать
func downsample(imageAt imageURL: URL, to pointSize: CGSize, scale: CGFloat) -> UIImage {    let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary    let imageSource = CGImageSourceCreateWithURL(imageURL as CFURL, imageSourceOptions)!        let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale    let downsampleOptions =        [kCGImageSourceCreateThumbnailFromImageAlways: true,         kCGImageSourceShouldCacheImmediately: true,         kCGImageSourceCreateThumbnailWithTransform: true,         kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels] as  CFDictionary    let downsampledImage =        CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions)!    return UIImage(cgImage: downsampledImage)}

QMAnimatedImageView Предоставляет интерфейс даунсемплинга, После открытия настроек Если ты сможешь сэкономить больше половины из Память, Кадры анимации будут автоматически сжаты в соответствии с размером экрана.

4.3.4 существующее декодирование не удалось при попытке вручную освободить Память

существовать App бег, часть API Что произойдет, если память не может быть запрошена NSMallocException крах, Авария описана как «Не удалось to grow buffer”. Картинки, как правило, да Память потребление крупных домохозяйств, Таким образом, вы можете увидеть, что декодирование изображения не удается, Активно попытайтесь освободить кэш памяти изображений, Позитивные фотографии существованияиспользоватьиз не будут опубликованы, Картина, которая не была использованаиз, была выпущена сначала, чтобы освободить Память, Избегайте дефицита Памяти, вызванного крахами.

4.4 Другие меры оптимизации

4.4.1 В скользящих сценариях задачи декодирования не выполняются, чтобы снизить нагрузку на ЦП.

существуют быстрый слайд из сцены, CPU Обычно он довольно занят. Так что можно сдвинуть не генерируя задачу декодирования кадра из иуменьшать CPU давление, QMAnimatedImageView Также предусмотрена функция экранирования интерфейса.

4.4.2 Настройки SDImageCache

SDImageCache 提供了最大кэшиз ПараметрыmaxMemoryCost, Да Мы раньше этого не делали сами, SDWebImage Постараюсь максимально занять Память, существовать MemoryWarning Освободите кэш памяти, когда Кривая памяти изменится, как горная вершина, существование продолжает испытывать грань опасности.

и В этой оптимизации я буду maxMemoryCost ценитьнастраиватьстановитьсяМаксимально доступная памятьиз 30%(онлайн ABT полученный), Кривая памяти будет очень плавной. может эффективно уменьшить OOM. 

Максимально доступная памятьизвычислить Код выглядит следующим образом:

Язык кода:javascript
копировать
// Получить процесс доступный единица (Byte)- (int64_t)memoryUsageLimitByByte{    int64_t memoryLimit = 0;    // Получить актуальные данные Памятьиспользовать    if (@available(iOS 13.0, *))    {        task_vm_info_data_t vmInfo;        mach_msg_type_number_t count = TASK_VM_INFO_COUNT;        kern_return_t kr = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vmInfo, &count);        if (kr == KERN_SUCCESS)        {
            // Косвенно получить верхний предел максимально доступного размера текущего процесса.            // iOS13+ можно рассчитать так: текущий процесс занимает Память+alsouseizПамять=верхнее предельное значение            int64_t memoryCanBeUse = (int64_t)(os_proc_available_memory());            if (memoryCanBeUse > 0)            {                int64_t memoryUsed = (int64_t)(vmInfo.phys_footprint);                memoryLimit = memoryUsed + memoryCanBeUse;            }        }    }
    if (memoryLimit <= 0)    {        NSLog(@"Не удалось получить доступную Память, использоватьфизика Памятьделатьдля进程可использовать Память");        int64_t deviceMemory = [NSProcessInfo processInfo].physicalMemory;        memoryLimit = deviceMemory * 0.55;    }
    if (memoryLimit <= 0)    {        NSLog(@"Не удалось получить физическую Память, использовать可использовать Памятьделатьдля进程可использовать Память");        // Обычно это значение намного меньше, Ничего из вышеперечисленного получить невозможно.        mach_port_t host_port = mach_host_self();        mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);        vm_size_t page_size;        vm_statistics_data_t vm_stat;        kern_return_t kr;
        kr = host_page_size(host_port, &page_size);        if (kr == KERN_SUCCESS)        {            kr = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);            if (kr == KERN_SUCCESS)            {                memoryLimit = vm_stat.free_count * page_size;            }        }    }    return memoryLimit;}

Ручная настройка maxMemoryCost После уменьшения картинки Память кэша попала из-за риска, Я также сделал соответствующую статистику, По мере увеличения коэффициента серой шкалы, Также Больше бизнеса переключитесь на QMAnimatedImageView , Скорость попадания в кэш Память на самом деле постепенно увеличивалась (в то же время MemoryWarning Количество триггеров также уменьшилось).

4.4.3 Создайте универсальное решение для загрузки изображений

Учитывая, что во многих сценах используется смесь статических изображений и анимации, Прежде чем загрузка существования будет завершена, Программа не знает url да нет нет анимированная картинка, QMAnimatedImageView После загрузки проверьте тип файла и номер кадра и логику, в соответствии Картинка актуального типа, чтобы открыть Загрузить покадрово,в то же времяподдерживать GIF/Animated WebP/APNG Три формата анимации, существующие могут загружать анимацию, а сцены можно использовать напрямую.

5. Сравните различные решения с открытым исходным кодом

После завершения трансформации, Является ли производительность нового решения лучше, чем у основного решения? Я подготовил более экстремальный сценарий, Создайте поток анимации, каждый Cell Содержит от трех до девяти анимированных картинок,Примерно тот же экран 20 个гифкасуществоватьвыставка, Общее количество использованных анимаций 200+, Проверьте ход анимации, проведя пальцем сверху вниз, а затем вверх и вниз вперед и назад. продолжительность 2 минута, Повторите для каждой сцены 3 в результате субсредний. Принимая во внимание онлайн-обвал, в основном да 3x Резолюция из 3G модель памяти, использовать iPhone 7 Plus в качестве испытательного оборудования. Сбор данныхиспользовать Instrument Инструменты для проверки использования памяти, использовать PerfDog Номер кадра теста также Катон, Сравнить одновременно UIImageView / SDAnimatedImageView / YYAnimatedImageView а также QMAnimatedImageView производительность, Результат следующий:

индекс

UIImageView

SDAnimatedImageView

YYAnimatedImageView

QMAnimatedImageView

пик памяти

1.9G

1.1G

1.3G

0.8G

Напряжение памяти триггера раз/мин

12

0.67

0

0

среднее количество кадров в секунду

52

36

57

58.3

Количество зависаний/10 минут

38

107

23

0

серьезный Количество зависаний/10 минут

25

9.8

15

0

Застрял и остановилсяпродолжительность Пропорция

12%

1.9%

0.9%

0%

Средняя загрузка ЦП приложения

48%

43%

81%

27%

данет авария

Тест вылетает через 5~40 секунд

нет

После 1-2 минут тестирования произойдет сбой.

нет

Подведите итог:

  • Используйте напрямую UIImageView, Почти да недоступен из-за, Хотя частота кадров неплохая, Очень застрял, Конкретную взаимосвязь между номером кадра и задержкой можно найти в статье. APP&Нужны игрысосредоточиться Это отставание Янка и скорость отставания[3].
  • SDAnimatedImageView CPU Заполняемость относительно низкая, Дарамка数只有 40 рамка вверх и вниз, Хотя количество серьезных зависаний меньше, Да После того как я испытал этода Очень застрял.
  • YYAnimatedImageView из Памятьа также CPU Заполняемость относительно высокая, существованиеиспользовать легко вызвать крах через одну минуту, Во время скольжения также наблюдается небольшая задержка. кроме тогопотому что YYImageCache Планирование очень консервативное, привести Скорость загрузки анимации явно выше, чем SDWebImage медленный.
  • и QMAnimatedImageView Никаких задержек на протяжении всего процесса, CPU Заполняемость остается на низком уровне, Память больше не будет расти после достижения верхнего предела настроек. существуют достижения лучшего баланса в планировании ресурсов.

6. Краткое изложение идей

основнойоптимизацияозначаета такжеглазиз:

  1. использоватьгифка Загружать покадровый план, следуетсуществовать анимационные картинки перед выставкой и она съела слишком много Память, и улучшить Первый кадр требует времени.
  2. использовать Image Привязать кадровый буфер, избегать YYAnimatedImageView Программа существует, постоянно загружает новые анимации в скользящую сцену и очищает кэш. к Всегда занимаюсь декодированием, вызвано CPU нагрузкаслишком высокий.
  3. настраивать SDImageCache из Память порога кэша, избегать CPU Когда нагрузка выше MemoryWarning Не сработало вовремя, привести к MallocException крах.
  4. использовать NSCache заменять NSDictionary сделать буферизацию кадров, наблюдать за сжатием системы Память приносит доп. CPU потребление, И буфер кадра автоматически освобождается системой.
  5. существовать Памятьнедостаточныйпривести к Активно отпускается при сбое декодирования SDImageCache из memoryCache, Внимание Другие бизнес-приложения не могут быть поданы на Памятьпривести ккрах.
  6. настраивать开启картинасубдискретизация, быть разумнымиспользовать Память.
  7. существовать, Когда основная нить скользит, Пауза декодирования новых кадров, посетить Быстрая трата скользящей сцены CPU ресурс.
  8. Завершите компонент универсальной загрузки изображения, существующие анимации и статические изображения можно повторно использовать непосредственно из сцен. QMAnimatedImageView, Компоненты не будут вызывать дополнительного потребления производительности.

7. Ссылки

[1]. iOS Memory Deep Dive

https://developer.apple.com/videos/play/wwdc2018/416/

[2]. Image and Graphics Best Practices

https://developer.apple.com/videos/play/wwdc2018/219/

[3]. APP&Нужны игрысосредоточиться на Джанк лаг и скорость лага?

https://bbs.perfdog.qq.com/article-detail.html?id=6

boy illustration
RasaGpt — платформа чат-ботов на основе Rasa и LLM.
boy illustration
Nomic Embed: воспроизводимая модель внедрения SOTA с открытым исходным кодом.
boy illustration
Улучшение YOLOv8: EMA основана на эффективном многомасштабном внимании, основанном на межпространственном обучении, и эффект лучше, чем у ECA, CBAM и CA. Малые цели имеют очевидные преимущества | ICASSP2023
boy illustration
Урок 1 серии Libtorch: Тензорная библиотека Silky C++
boy illustration
Руководство по локальному развертыванию Stable Diffusion: подробные шаги и анализ распространенных проблем
boy illustration
Полностью автоматический инструмент для работы с видео в один клик: VideoLingo
boy illustration
Улучшения оптимизации RT-DETR: облегченные улучшения магистрали | Support Paddle облегченный rtdetr-r18, rtdetr-r34, rtdetr-r50, rtdet
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | Деформируемое внимание с большим ядром (D-LKA Attention), большое ядро ​​​​свертки улучшает механизм внимания восприимчивых полей с различными функциями
boy illustration
Создано Datawhale: выпущено «Руководство по тонкой настройке развертывания большой модели GLM-4»!
boy illustration
7B превышает десятки миллиардов, aiXcoder-7B с открытым исходным кодом Пекинского университета — это самая мощная модель большого кода, лучший выбор для корпоративного развертывания.
boy illustration
Используйте модель Huggingface, чтобы заменить интерфейс внедрения OpenAI в китайской среде.
boy illustration
Оригинальные улучшения YOLOv8: несколько новых улучшений | Сохранение исходной информации — алгоритм отделяемой по глубине свертки (MDSConv) |
boy illustration
Второй пилот облачной разработки | Быстро поиграйте со средствами разработки на базе искусственного интеллекта
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция с нулевым кодированием и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
Решенная Ошибка | Загрузка PyTorch медленная: TimeoutError: [Errno 110] При загрузке факела истекло время ожидания — Cat Head Tiger
boy illustration
Brother OCR, библиотека с открытым исходным кодом для Python, которая распознает коды проверки.
boy illustration
Новейшее подробное руководство по загрузке и использованию последней демонстрационной версии набора данных COCO.
boy illustration
Выпущен отчет о крупной модели финансовой отрасли за 2023 год | Полный текст включен в загрузку |
boy illustration
Обычные компьютеры также могут работать с большими моделями, и вы можете получить личного помощника с искусственным интеллектом за три шага | Руководство для начинающих по локальному развертыванию LLaMA-3
boy illustration
Одной статьи достаточно для анализа фактора транскрипции SCENIC на Python (4)
boy illustration
Бросая вызов ограничениям производительности небольших видеокарт, он научит вас запускать большие модели глубокого обучения с ограниченными ресурсами, а также предоставит полное руководство по оценке и эффективному использованию памяти графического процессора!
boy illustration
Команда Fudan NLP опубликовала 80-страничный обзор крупномасштабных модельных агентов, в котором в одной статье представлен обзор текущего состояния и будущего агентов ИИ.
boy illustration
[Эксклюзив] Вы должны знать о новой функции JetBrains 2024.1 «Полнострочное завершение кода», чтобы решить вашу путаницу!
boy illustration
Краткое изложение базовых знаний о регистрации изображений 1.0
boy illustration
Новейшее подробное руководство по установке и использованию библиотеки cv2 (OpenCV, opencv-python) в Python.
boy illustration
Легко создайте локальную базу знаний для крупных моделей на основе Ollama+AnythingLLM.
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание решения. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Одна статья поможет вам понять RAG (Retrival Enhanced Generation) | Введение в концепцию и теорию + практику работы с кодом (включая исходный код).
boy illustration
Эволюция архитектуры шлюза облачной разработки
boy illustration
Docker и Kubernetes [Разработка контейнерных приложений с помощью Python]