Как увеличить производительность приложения
Думаю, многие сталкивались с такой проблемой: игры запускаются чертовски долго. Пока это происходит можно налить чаю, убрать квартиру, сходить в магазин, прийти обратно и увидеть, что Fortnite ещё в загрузочном экране. Эту проблему призвана решить программа PrimoCache . Например без её использования на запуск Fortnite ушла 1 минута 42 секунды, а уже с включённой утилитой ровно 1 минута.
Установка программы
- Скачайте файл
- Запустите его и пройдите стандартный процесс установки
- После вам предложат перезапустить компьютер - так и делаем
Настройка программы
Итак, после перезагрузки вашего устройства нужно настроить PrimoCache .
Запускаем её от имени администратора и нажимаем на зелёный плюсик
В этом окне выбираем - какой диск ускорить. Например я хочу сделать это с диском E - ставим галочку и нажимаем "Next"
На этом этапе перед нами предстает окно, где нужно выбрать количество ОЗУ ( оперативной памяти ) которое будет использовать программа. Также необходимо нажать на галочку «Enable Defer-Write» . Теперь можно нажимать «Start»
Принцип работы PrimoCache
У каждого жесткого диска или ssd накопителя есть кэш память, в ней собираются данные, которые уже считаны с диска, но ещё не запрошены на обработку. Как правило, размер этой памяти на всех накопителях равняется 32мб или 64мб, а её скорость соответствует скорости накопителя. Стоит ли говорить, что любая оперативная память быстрее в разы. Так вот, программа PrimoСache заставляет компьютер использовать ОЗУ в качестве Кэш памяти.
Моменты, на которые нужно обратить внимание
- Необходимо отключить Windows Fast Startup, иначе после перезагрузки компьютера Кэш программ не сохранится. О том, как это сделать, немного позднее
- Программы начнут запускаться быстрее только на второй или даже на третий раз. PrimoCach нужно создать кэш, так что с первого раза вы не увидите изменений в скорости загрузки программ
Как отключить Windows Fast Startup
Нажимаем одновременно Win + R - перед нами возникает окно реестра. Вводим в него команду: regedit
Современные ЭВМ обладают очень большой мощностью. Скорость работы процессора (ЦП) современных ЭВМ измеряется гигагерцами, объём оперативной памяти гигабайтами, а современные интерфейсы устройств обеспечивают скорость обмена данными порядка, как минимум, нескольких сотен мегабайт в секунду [1]. Производительность, которая ещё несколько лет назад казалась «сказочной» в настоящее время стала нормой жизни.
Однако параллельно росту мощности ЭВМ увеличивается и ресурсоёмкость приложений. У приложений совершенствуется функционал, интерфейс, возрастает объём обрабатываемых данных и как следствие системные требования. Поэтому вопрос об увеличении быстродействия приложений не теряет своей актуальности.
Общие вопросы быстродействия программ.
Быстродействие программ (ПО) зависит от многих факторов, но основными из них являются два:
- Соотношение между реальными системными требованиями ПО и существующей аппаратной конфигурацией ЭВМ;
- Алгоритмы работы ПО.
Если низкое быстродействие обусловлено первым фактором, то решением является модернизация аппаратной части (hardware). В некоторых случаях проблему можно решить также с помощью тонкой настройки hardware и операционной системы. Однако этот путь имеет ряд недостатков:
- Увеличивается производительность hardware, а вовсе не быстродействие ПО;
- Производительность hardware ограничена возможностями существующих в данный момент элементной базы и инженерных решений в данной области;
- Большие финансовые затраты на модернизацию и настройку по причине высокой стоимости комплектующих ЭВМ и услуг специалистов требуемой квалификации.
По этим причинам при разработке ПО прибегают к увеличению его быстродействия с помощью различных средств программной инженерии. Это позволяет:
- Обеспечить работу нового ПО на уже существующем оборудовании;
- Разработать масштабируемое ПО;
- Значительно уменьшить финансовые и трудовые затраты при внедрении.
Вместе с тем и у этого пути имеется ряд недостатков:
- Значительно усложняется процесс разработки ПО, так как более «быстрые» алгоритмы сложнее более «медленных» (на пример алгоритм бинарного поиска сложнее, чем алгоритм линейного поиска) [2];
- Реализация более сложных алгоритмов, как правило, требует привлечения специалистов более высокой квалификации;
- В случае работы с большими объёмами данных или выполнении задач требующих больших и сложных вычислений, ресурсоёмкость ПО всё равно остаются достаточно высокой. Несмотря, на какие либо способы увеличения быстродействия.
Таким образом, в общем случае обеспечение быстродействия ПО является комплексной задачей.
Однако следует заметить, что среди существующих задач, очень немногие обладают высокой ресурсоёмкостью. Вследствие этого в большинстве случаев не требуется никаких действий относительно hardware и требуемого результата можно достичь, прибегая только к программной инженерии.
Программная инженерия предоставляет несколько способов увеличения быстродействия программ. Рассмотрим их на примере языков программирования Delphi и Assembler.
Увеличение быстродействия программ.
Как было показано в предыдущем параграфе, можно увеличить быстродействие ПО соответствующим образом реализовав его алгоритмы. Количественным показателем быстродействия алгоритма (а, следовательно, и ПО) является время его выполнения, измеренное по специальной методике, так называемого профилирования [2]. Таким образом, в общем случае выбор наиболее «быстрых» алгоритмов сводится к измерению времени их выполнения и сравнении полученных результатов между собой. Такой способ анализа быстродействия является наиболее объективным [2]. На протяжении многих лет программистами был накоплен большой опыт профилирования, который позволяет сделать определённые выводы относительно возможности оптимизации быстродействия ПО ещё на стадии написания.
Эти выводы были обобщены и представлены в виде определённых рекомендаций [2, 4]. Если программист будет следовать данным рекомендациям, то написанная программа вероятнее всего будет обладать большим быстродействием, чем в случае их игнорирования. Однако следует ещё раз подчеркнуть, что достоверные сведения о быстродействии может дать только профилирование. Это обусловлено тем, что быстродействие алгоритма определяет в первую очередь его конкретная реализация. Кроме того необходимо ещё раз отметить, что в отношении увеличения быстродействия ПО программная инженерия не всесильна (см. предыдущий параграф).
В чём же состоят выше упомянутые рекомендации? Их краткое содержание применительно к языку программирования Delphi приведено ниже.
Особо следует отметить, что рекомендации 3 и 4 применяются не только для языков высокого уровня, но и для ассемблера. Помимо вышеуказанных для увеличения быстродействия программ написанных на ассемблере, в том числе и вставок, существуют следующие рекомендации [3]:
Заключение.
Методы оптимизации быстродействия, рассмотренные в этой статье, были выработаны и проверены не одним поколением программистов и уже стали классическими. В то же время информационные технологии, в частности технологии программирования, постоянно развиваются. Появляются новые технологии, старые – модернизируются или уходят в прошлое. Растёт производительность аппаратной части ЭВМ и параллельно с этим растёт сложность и ресурсоёмкость выполняемых ими задач.
Поэтому вопрос оптимизации быстродействия сейчас актуален также как и много лет назад. Более того он будет также актуален и в будущем.
В этой небольшой статье я хочу поделиться с вами опытом, как программно оптимизировать производительность приложения Андроид за 5 простых шагов на примере создания цифровой версии игры «Корона Эмбера».
До создания серьезных приложения со сложной структурой View и Layout'ов мы особо не задумывались над тем, как простые и логичные действия в стиле «смотрите, я набросал дизайн из лэйаутов» могут серьезно замедлить работу всей программы.
Помимо прочего, задача с «Короной Эмбера» осложнялась еще и тем, что игра, которую мы задумали перенести на Андроид платформу, была сама по себе достаточно насыщенной различными компонентами, которые как-то надо было умещать на игровом поле или рядом с ним.
В статье я собрал наш успешный опыт и облёк его в удобную и читабельную форму, полезную для тех, кто все еще гуглит «как программно оптимизировать приложение под Андроид» или «почему мое приложение лагает».
Итак. Исходная точка (то, как это все выглядело ДО оптимизации)
Дизайн приложения был создан из «правильной» кучи около двух сотен View и десятка Layout'ов. Загрузка игрового поля происходила около 5 секунд, а почти каждое действие зависало еще на 1-2 секунды. И если на прогрессивных устройствах и эмуляторах лаги были практически незаметны, то на большинстве менее современных устройств картина выглядела достаточно печальной.
Понятно, что это не устраивало ни меня, ни нашу команду, ни тестеров. И хотя мы были искреннее уверены, что все оптимизировано дальше некуда, мы принялись искать информацию.
Часть знаний, которыми я хочу поделиться, мы нашли здесь — классные видео-уроки с русскими субтитрами (рекомендую), часть — на Хабре, часть — в глубинах Интернета, на том же сайте Google Developers.
Причем, каждый раз получая новую порцию и проводя очередную оптимизацию, мы были уверены «все теперь дальше некуда, быстрее не будет» и с каждым шагом открывали для себя все больше и больше нового.
И вот, как это происходило.
Шаг 1. Измерение
По сути это даже не шаг, а настойчивая рекомендация постоянно измерять свою производительность. Для этого в Андроид Студио предусмотрено несколько специальных программ: Android Device Monitor с HierarhyViewer, SystemTracing, Method Profiling; Android Monitor с Memory, CPU и GPU мониторами. Описывать их работу не цель данной статьи, вы легко можете найти гайды здесь же, на Хабре, или в упомянутых видео-уроках.
Суть в том, что чтобы оптимизировать производительность, нужно сначала понять где же она «спотыкается».
Хотя, даже без измерения, есть несколько вещей, на которые необходимо обращать внимание каждому разработчику и мы шагаем дальше.
Шаг 2. Оптимизация иерархии и снижение веса
Основная потеря производительности приложений происходит при пересчете и перерисовке отображенных Layout'ов. Причем чем «тяжелее» лэйаут — тем дольше происходит перерасчет его показателей. И тут надо обратить внимание на следующие моменты:
— в вашей иерархии не должно быть вложенных LinearLayout с параметрами «weigh» (вес). Измерение такого лэйаута занимает в два (три, четыре! — в зависимости от вложенности) больше времени. Лучше заменить эту конструкцию на GridLayout (или support.v7.GridLayout для API меньше 21);
— некоторые LinearLayout можно заменить на RelativeLayout, тем самым убрав дополнительные вложения, например;
— оказывается, RelativeLayout также измеряется дважды. Где возможно — его нужно заменить на более «легкий» FrameLayout.
Изучив нашу разметку мы с ужасом обнаружили, что в ней есть вложенные до четырех (!) раз LinearLayout с параметром вес, игровое поле состоит из почти сотни RelativeLayout (клетки поля), а некоторые Layout просто не нужны.
(Зеленым отмечено допустимое вложение, желтым — нежелательное, оранжевым — опасное, красным — «никогда-так-не-делайте!»)
После этого мы немного переработали структуру. «Персонажа» вынесли в отдельный фрагмент с RelativeLayout, все вложенные Linear заменили на (один!) support.v7.GridLayout, а все RelativeLayout (на скрине их не видно — это клетки поля) заменили на FrameLayout. Получилось и симпатишней и производительней.
Однако до конца наши проблемы это не решило, и мы пошли дальше.
Шаг 3. Лишняя перерисовка (Overdraw)
Оказалось, что Андроид тщательно прорисовывает каждую картинку, каждый background у каждого View на экране. Здесь он, конечно, молодец. Но что делать, если одни изображения перекрывают другие, бэкграунды накладываются и часть этой прорисовки становится абсолютно ненужной? Правильно — отключать все, что не видно и не нужно.
Измерить наложение перерисовки оказывается очень просто: на своем устройстве в «Параметрах разработчика» нужно включить «Показывать превышение GPU», запустить приложение и посмотреть на экран.
Цвета View-элементов покажут, насколько у вас все хорошо (или плохо).
Свой цвет — уровень 0, «идеально»
Синий цвет — уровень 1, «нормально.
Зеленый цвет — уровень 2, „допустимо“.
Светло-красный цвет — уровень 3, „нежелательно“.
Красный цвет — уровень 4+, „не дай бог“.
Наша картинка вновь ввергла нас в ужас:
Нам пришлось снова пройтись по всей разметке и отключить background там, где он оказался лишним. Не забыли и про основной бэк приложения — одной простой строчкой:
В теме приложения выключили и его. И вот что получилось в итоге. Может и не везде идеально, но вполне допустимо. (Почти все View опустились на 3 уровня!)
Шаг 4. Кэширование — ключ к успеху
Тоже вполне очевидная вещь, которая не казалась обязательной — это кэширование. В частности (в данном случае) кэширование шрифта.
Как вы уже наверное обратили внимание, везде, включая логи, используется свой шрифт и, о (опять) ужас!, каждый раз, для каждого нового текста он подгружается заново из Assets. Каждый раз, Карл! (черным цветом — основной потом, коричневым — работа Assesnager'а).
С кэшированием до этого никто из нас не сталкивался, но тут нас выручил один хороший человек со StackOverflow и подсказал простой код:
Применив который, лично я вообще практически забыл, что такое лаги.
Шаг 5. „А это — под укроп!“
Как в анекдоте, где мужику сказали, что он получит под надел столько земли, сколько сам сможет измерить и он скакал, бежал, шел, полз и в конце изможденный снял с себя шапку и кинул на сколько смог со словами: „А это — под укроп“, так и мы стремились максимально до мельчайших деталей оптимизировать производительность.
Поэтому пришло время оптимизации кода. Конечно, то как пишется код — это уже больше дело правильной привычки, и тут можно только дать несколько общих рекомендаций (более подробно их можно найти в любой статье по программной оптимизации). Вот с чем столкнулась наша команда:
— создавайте поменьше „ненужных“ циклов. Если что-то можно сделать без них — делайте без них;
— не создавайте переменных в цикле. Лучше создать их за его пределами, а в цикле просто обновлять;
— если есть необходимость обратиться к ресурсам неоднократно (с помощью gerResources() или же просто в другой класс/массив, например, myList.get (0)) — лучше запишите полученный результат в новую переменную и используйте ее: int myItem = myList.get(0); — это тоже подарит вашему приложению миллисекунды свободного времени;
— по возможности используйте статические методы (если нет необходимости обращаться к самому классу);
— ну и классический способ: на финальном этапе программирования убирайте инкапсуляцию (геттеры и сеттеры) и обращайтесь к переменной напрямую.
Подводя итог
Уверен, что сделанные шаги не являются окончательными и всегда будет „место под укроп“, до которого мы не добрались. Всегда готов узнать о шаге №6, 7… и даже №157, если вы захотите ими поделиться в комментариях. Более того, за „науку“ буду благодарен.
А пока, резюмируем, что же нужно сделать, чтобы ваше приложение начало „летать“:
1. Измерьте производительность своего приложения и найдите источник проблемы. Может у вас это будет не шрифт, а, например, утечка памяти (включаем Memory Monitor);
2. Оптимизируйте структуру и иерархию View (включаем HierarhyViewer и здравый смысл);
3. Убираем везде все ненужные бэки, включая background приложения (в этом случае учтите, что для корректного отображения вам все равно понадобится общий бэк);
4. Смотрим на часто используемые ресурсы/загрузки/картинки/шрифты и кэшируем их;
5. Делаем оптимизацию программного кода.
В итоге, после всех этих шагов, картинка трассинга приложения стала выглядеть вот так:
задержки практически исчезли (или стали незаметны), что нас вполне устроило.
Ну и конечно, первая мысль, которая пришла ко мне в голову после всей нашей оптимизации: „Вау! Теперь же можно добавить еще больше View и Layout на основной экран!“
Windows 10 до определенной поры была очень быстрой ОС дающей отличную плавность в играх. Но каждое очередное полугодовое обновление что-то меняло в недрах системы, добавлялись новые функции не очень хорошо отразившиеся на отклике в играх - GameBar, глубокая модернизация DWM, не отключаемый синтетический QPC таймер или оконный режим без рамок. В результате отклик системы на версиях ОС старше 1607 становился все хуже, а масштабы бедствия легко понять, погуглив запросы "latency issue", "фризы Windows 10" или "лаги Windows 10".
реклама
Что самое печальное, плавности работы не ощущается даже в Проводнике, ведь Windows 10 состоит из сотен взаимозависимых процессов, каждый из которых может "упасть", зависнуть, перезапустится, что вызовет всем знакомый "кружочек ожидания" на рабочем столе или провал кадровой частоты в игре. Даже для открытия меню "Пуск" Windows 10 считывает данные из одного файла более ста тысяч раз! Проводник затрачивает 700 мс (почти секунду!) на открытие контекстного меню панели задач, 75% этого времени он выполняет более сотни тысяч операций считывания из одного файла, а средний объём считываемых данных составляет всего 68 байт.
реклама
var firedYa28 = false; window.addEventListener('load', () => < if(navigator.userAgent.indexOf("Chrome-Lighthouse") < window.yaContextCb.push(()=>< Ya.Context.AdvManager.render(< renderTo: 'yandex_rtb_R-A-630193-28', blockId: 'R-A-630193-28' >) >) >, 3000); > > >);Это все, что нужно знать об оптимизации Windows 10, а изменений в лучшую сторону не предвидится, ведь Windows 10 останется практически в том виде, в котором существует сейчас, до конца своего жизненного цикла. А Windows 11, на которую пользователи возлагали надежды как на ОС в которой исправят то, что нам не нравилось в Windows 10, оказалась лишь очередным большим обновлением Windows 10, которое получило имя "Windows 11".
Похоже, заявление Microsoft о том, что Windows 10 станет последней Windows, де-факто оказалось точным и по крайней мере ближайшие пять лет мы будем пользоваться Windows 10 под видом Windows 11.
реклама
Что может сделать пользователь, стремящийся к максимальному отклику и отзывчивости в играх? Первый путь - это пробовать пользоваться устаревшими ОС, такими как Windows 7, Windows 8.1 или Windows 10 1607. Это даст отличный результат, но в некоторых играх пиковая производительность может стать хуже из-за старых версий Windows Display Driver Model. А для игр с DirectX 12 (но не всех, некоторые идут и под Windows 7) это не подходит.
Второй путь - глубокая оптимизация системы с вырезанием под корень ненужных функций и сервисов. Производиться оптимизация может как вручную, так и с помощью твикеров, на уже установленной системе или над ее установочным образом. Минусы такого подхода в том, что мы нарушаем взаимосвязь некоторых процессов, ведь полностью подчистить все "хвосты" и удалить функции начисто не удалось даже Microsoft в версиях LTSB и LTSC.
И настроенная таким образом система может впасть в ступор или даже "крашнуться" на пустом месте, а еще одним минусом становится способность ОС восстановить свои отключенные части и включить сервисы, ведь наши твики она считает за повреждения.
реклама
И, наконец, третий путь, который я предлагаю в этом блоге - отключить часть функций средствами системы, корректно и безопасно, не нарушая ее целостности и с возможностью вернуть все к настройкам по умолчанию. С таким подходом мы получаем максимум результата при минимуме затраченных усилий, а система не теряет стабильности. Давайте разберемся с десяткой проверенных настроек Windows 10 которые сможет сделать даже начинающий пользователь и которые дадут вам максимальную плавность и быстрый отклик в играх.
Добавляем в исключения Microsoft Defender папку игры и ее процесс
Защитник Windows, который теперь называется Microsoft Defender полностью отключить все проблематичнее, а его поведение зачастую слишком активное, что отражается на отклике системы, которую он может загрузить почти на 100%. Поэтому совсем не помешает добавить папку с вашими играми в его исключения, а дополнительно - и процессы игр, даже лицензионных. К примеру, это помогло мне победить вылеты на рабочий стол в Anno 1800.
Отключаем запись экрана в фоновом режиме
Запись в фоновом режиме может замедлить даже ПК среднего уровня, и крайне рекомендуется ее отключить. Не помешает и полностью отключить Xbox Game Bar, ведь функции, которые он выполняет, мы привыкли использовать более удобно с помощью сторонних утилит.
Включаем планирование графического процессора с аппаратным ускорением
В некоторых случаях включение этой функции прибавит пару процентов FPS, что совсем не помешает.
Устанавливаем режим максимальной производительности
На обычном игровом ПК пользы от энергосбережения не очень много и лучше перевести ПК в режим повышенной производительности, что даст более быстрый отклик системы.
А программное отключение сбрасывания частоты процессором может дать отличные результаты на некоторых ПК.
Активируем игровой режим
Активация игрового режима отключит уведомления, которые могут вызывать фризы при появлении, отдаст приоритет игровому процессу и запретит центру обновлений Windows выполнять установку драйверов.
Отключаем акселерацию мыши
Акселерация или повышенная точность указателя может вызывать проблемы с поведением мыши в играх и ее рекомендуется отключить.
Ручная установка драйверов для видеокарты и материнской платы
Windows 10 по умолчанию сама устанавливает драйвера устройств и это очень удобно если вам не нужны самые свежие драйвера. В противном случае это стоит отключить, найдя указанный параметр в подразделе "Устройства и принтеры". Назван он не явно, но функцию отключения загрузки драйверов выполняет.
Откладываем обновления
Не прошло и пяти лет как в Windows 10 появилась функция приостановки обновлений, которые стоили миллионов нервных клеток, потраченных пользователями. Качество обновлений Windows 10 оставляет желать лучшего, но критические уязвимости, такие как свежая уязвимость диспетчера очереди печати Windows Print Spooler, автоматически можно закрыть только на обновляемой системе. Хорошим выходом будет приостановка обновлений на пару недель - и баги в обновлениях успеют пофиксить, и ОС получает их довольно оперативно.
Оставляем на SSD достаточное количество свободных гигабайт
Достаточное свободное место на SSD нужно не только для продления его ресурса, но и для достижения максимальных скоростных характеристик, поэтому совсем неплохо будет держать 30-50 ГБ свободными. А недорогие SSD, забитые почти под завязку, могут и вовсе впадать в ступор, когда операции чтения и записи прерываются на несколько секунд вызывая жуткие тормоза в играх.
Не беспокоиться о свободном месте и ресурсе вам позволит надежный SSD объемом 500 ГБ, например, WD Blue (WDS500G2B0A) из магазина Регард. Он имеет SATA интерфейс и подойдет к любому ПК, даже очень старому.
А вот M.2 модель WD Blue SN550 (WDS500G2B0C) с интерфейсом PCI-E x4 отлично подойдет в современные производительные ПК.
Переносим файл подкачки на SSD и выбираем размер "По выбору системы"
Совсем недавно любой уважающий себя гайд по оптимизации Windows содержал в себе прямо противоположные требования - "файл подкачки отключаем или переносим с SSD на жесткий диск". О нужности файла подкачки для стабильной работы системы при достаточном объеме ОЗУ уже написано немало гайдов, а вот экономить ресурс SSD замедлением работы "заменителя ОЗУ" не стоит - все равно потратить его ресурс скорее всего не получится, а вот некоторые игры требуют больших размеров файла подкачки и лучше, если выделение места для них будет происходить в автоматическом режиме.
А иногда игры страдают утечками памяти, в этом случае файл подкачки на SSD предотвратит ранний "краш" игры и даст вам спокойно поиграть.
Итоги
Опытному пользователю советы из блога могут показаться слишком простыми, но все они являются щадящими для системы и позволят вашей Windows 10 работать стабильно и быстро месяцами. Пишите в комментарии, какие еще настройки вы добавили бы в этот список?
Читайте также: