быстродействие программы что это
Производительность программы против читаемости и простоты кода: в пользу чего стоит делать выбор?
Авторизуйтесь
Производительность программы против читаемости и простоты кода: в пользу чего стоит делать выбор?
Одной из сильных сторон C++ является возможность написания очень производительного кода. Но значит ли это, что мы должны постоянно беспокоиться о производительности и писать весь код настолько производительно, насколько это возможно? Должны ли мы отказаться от простоты ради этого? А стоит ли?
Лично я так не думаю и могу привести много причин, почему не стоит жертвовать простотой и чистотой кода для повышения производительности. Я бы предпочел, чтобы все изначально писали простой и чистый код. Вот несколько из причин для такого выбора.
Производительность ≠ эффективность
В первую очередь нужно научиться различать производительность и эффективность. В чем разница? Если коротко: производительность влияет на то, как быстро вы что-то делаете, а эффективность — на то, сколько это занимает у вас времени.
Вроде бы одно и то же, скажете вы, и будете неправы. Представьте, что вы перемещаетесь из пункта А в пункт Б. Эффективно будет пойти кратчайшим путем. Производительно будет, если вы побежите. То есть, если вы на всех парах промчитесь по всему району, чтобы попасть к соседу, это будет производительно, но не эффективно.
В программировании циклы сильно влияют на время выполнения программы. В этом случае производительность будет отвечать за время выполнения одной итерации, а эффективность — за их количество, которое можно уменьшить лучшим алгоритмом.
Иногда эти понятия не пересекаются. Более эффективный алгоритм может быть менее производительным. Однако, прежде чем выжать максимум производительности из участка кода, убедитесь, что он эффективен. Только когда вы учли все возможности в плане эффективности, можно начать заниматься повышением производительности.
Порой для получения желаемой скорости достаточно повысить эффективность кода и не беспокоиться о производительности.
Производительность нужна не всегда
Это очевидно, но многие программисты, особенно начинающие, не всегда понимают это. На форумах висят сотни вопросов об оптимизации кода. При этом, если задается вопрос о том, является ли этот участок кода «бутылочным горлышком» для общей производительности, ответ на него чаще всего дается отрицательный.
Говорят, что 80% времени своей работы программа занимается выполнением 20% кода. Но точные числа здесь не важны. Главным является тот факт, что программа тратит большую часть времени на исполнение меньшей части кода.
Иными словами, это означает, что почти весь код мало влияет на время выполнения, и его оптимизация прироста скорости не даст.
Не оптимизируйте код, который не влияет на общую производительность программы.
На самом деле мы не знаем, как правильно оптимизировать
О да, как я посмел 🙂 Дело в том, что огромное влияние на время выполнения программы имеет количество инструкций, исполняемых процессором. А их задаем не мы, а компилятор и его оптимизатор.
Оптимизаторы бывают разные, и если вы не эксперт, то вряд ли вы догадаетесь, что они делают с нетривиальным участком кода. Оптимизаторы могут удалять временные объекты, делать функции встроенными, порой даже во время линкования, и даже перемешивать и удалять многие из этих инструкций.
Так что мы можем сделать для повышения производительности с учетом этих суперсил компилятора и нашего незнания того, какой код оптимален? На первый взгляд — ничего. И если мы действительно беспокоимся о производительности, стоит положиться не на воображение и опыт, а на инструменты.
Изначально пишите поддерживаемый код, поскольку он вполне может быть достаточно производительным. Для улучшения производительности используйте профайлер.
Производительность и простота — не взаимоисключающие признаки
Серьезный вклад во время выполнения программы также вносит структура и расположение данных в памяти. Об этом можно прочитать хорошую статью, я не буду заострять свое внимание на этом вопросе.
Главное — если вы плохо структуризовали данные в памяти, это точно приведет к ухудшению производительности.
Убедитесь, что вы используете самые производительные структуры данных, прежде чем начать оптимизировать сам код.
Есть еще один способ написания производительного и простого кода: используйте проверенные библиотеки. Их авторы, как правило, умные ребята, и разбираются в производительности. Поэтому, если вы будете использовать библиотеки, а не свои решения, код будет не только проще, но и производительней.
Используйте библиотеки, но только если профайлер не жалуется на их плохую производительность.
Заключение
Изначально пишите простой и читаемый код. Если же вы нашли проблему в производительности, исправить ее можно, не превращая код в быстрый, но непонятный беспорядок. Жертвуйте простотой ради производительности только в крайнем случае, и всегда используйте профайлер.
А что вы думаете по этому поводу? Делитесь мнениями в комментариях, и да начнётся холивар 🙂
Что такое производительность веб-приложений?
Какие-то приложения грузятся быстро, какие-то медленно, но за счет чего это происходит? Только ли скорость загрузки страницы является показателем производительности приложения?
Ответить на эти и многие другие вопросы в одной статье было бы очень сложно. Поэтому я собрал каталог ссылок и разбил его на категории. Но для начала — немного теории о том, что такое производительность и когда о ней стоит задуматься.
Когда возникают проблемы с производительностью
Вы можете годами разрабатывать веб-приложения и практически не сталкиваться с проблемами производительности приложений.
Но, вероятнее всего, проблемы возникают в следующих ситуациях:
Из чего состоит производительность
Глобально проблемы с производительностью веб-приложений можно разделить на две категории: передача данных и runtime.
Вот самые популярные метрики производительности веб-приложений (все должны быть минимальными):
Загрузка страницы
Runtime
Как искать и анализировать проблемы с производительностью
Основным набором инструментов в арсенале разработчика является Chrome DevTools или аналогичные инструменты, например Firebug/Firefox developer tools.
Про них можно писать отдельные статьи, но мы ограничимся самыми важными моментами.
Network — позволяет подробно проанализировать, какие ресурсы загружаются на странице, с каких ресурсов, с какой скоростью и так далее. Этот инструмент часто используется для ручного анализа скорости загрузки страницы.
Performance — в этой вкладке можно включить запись вызовов исполнения кода, операций ввода/вывода и других. Помимо этого запись можно делать с эмуляцией троттлинга сети и CPU. Например, проверить работу приложения на слабых устройствах.
Lighthouse — инструмент, встроенный в Chrome DevTools, который запускает загрузку страницы, записывает метрики, делает по ним анализ и даже выдает рекомендации по улучшению производительности.
Как измерять/мониторить производительность
Инструменты для мониторинга производительности веб-приложений можно разделить на две категории: те, что производят синтетические измерения и те, что записывают данные производительности с реальных пользователей.
Передача данных
TCP connection, DNS lookup — ускорить загрузку страницы можно даже за счет правильной конфигурации подключений к серверу. В частности, если использовать DNS pre-fetching или даже IP-адреса вместо доменных имен.
TTFB (Time to First Byte). Время до получения первого байта — это важная метрика. Для ее ускорения нужно стараться реализовывать как можно меньше логики на сервере перед выдачей index.html.
HTTP1 vs HTTP2 — HTTP2 может сильно ускорить загрузку страницы за счет мультиплексирования или сжатия заголовков. Помимо этого, новый (относительно) протокол открывает кучу возможностей, например server push.
Domain sharding. Если для запросов к API вам нужно передавать много HTTP заголовков, а для запросов к статике — нет, то лучше разделить их по разным доменам.
CDN (content delivery network) поможет ускорить загрузку для территориально распределенных клиентов.
Resource prioritization (preload, prefetch, preconnect) — это ускорение загрузки страницы за счет правильной стратегии загрузки ресурсов. Браузеры позволяют устанавливать приоритеты для разных типов ресурсов и загружать раньше то, что важно для первой отрисовки.
Static compression: GZIP and Brotli. Brotli — это алгоритм сжатия, который уменьшит вес статики и, соответственно, увеличит скорость загрузки. А вот отличное решение от моего коллеги.
Webp vs Png & Jpg. Webp — отличная альтернатива Png. Помимо меньшего веса изображений, Webp не уступает по качеству. Сейчас этот формат поддерживает примерно 78% браузеров. Но даже если вам нужна 100% поддержка, можно реализовать фоллбэк на Png с помощью тэга picture.
Runtime
Tasks, Microtasks. С помощью правильной приоритизации выполнения кода можно избавиться от «фризов» и ускорить реагирование на пользовательский ввод.
requestIdleCallback — полезная функция, которая позволяет выполнить код в свободное время в конце кадра (фрейма/тика) или когда пользователь неактивен. Поможет избавиться от всех тех же лагов и «фризов».
requestAnimationFrame позволяет правильно запланировать анимацию и максимально увеличить шансы на рендеринг 60 кадров в секунду.
ES2015 vs ES5. ES2015 предоставляет много функций, более производительных, чем ES5.
DOM manipulation. Манипуляции с DOM — дорогие, выполнять их нужно аккуратно и осмысленно. Например, не вызывать querySelector() в цикле, если это можно сделать одним вызовом.
Render blocking resource. Загрузка некоторых ресурсов может блокировать рендеринг. Чтобы этого избежать, нужно пользоваться атрибутами defer, async, preload.
60 FPS by pointer-events: none — отличный хак, с помощью которого можно достичь 60 FPS при скролле страницы. Работает очень просто: на время прокрутки отключаются все обработчики события мыши.
Passive event listener — способ сделать плавную прокрутку страницы на сенсорных экранах. Коротко говоря, браузер имеет несовершенный флоу обработки слушателей touch events. Если при создании обработчика события установить параметр passive, то браузер будет однозначно понимать, что обработчик не будет отменять прокрутку и рендерить, не дожидаясь его завершения.
Virtual scroll — умный способ не рендерить большие списки, а генерировать их при прокрутке. Позволяет потреблять меньше памяти и облегчить скроллинг списков.
Avoid large Complex Layouts and Layout Thrashing. Layout/reflow — это дорогие операции, которые выполняют много пересчетов параметров рендеринга. Чтобы избегать их частого вызова, нужно правильно строить верстку и манипулировать DOM.
What forces layout / reflow — шпаргалка, в которой можно найти список функций и параметров, работа с которыми вызывает layout/reflow.
Сборка
Tree shaking — убираем неиспользуемый код из бандла и ускоряем загрузку страницы.
Code splitting — разделив код на чанки, можно оптимизировать первую загрузку и открыть возможность загружать части кода «лениво».
Obfuscation может уменьшить размер бандла и даже немного поможет скрыть ваш код от чужих глаз.
Архитектура
Server side rendering — наверное, самый известный способ сделать так, чтобы SPA рендерилось сразу, при первой загрузке. Это важное требование для некоторых поисковых систем (и не только).
Lazy loading images and video (+native) — нативное решение, призванное улучшить метрики первой отрисовки за счет «ленивой» загрузки изображений и видео.
Lazy loading modules/routes — инструмент, который есть во всех популярных фреймворках и библиотеках. Позволяет «лениво» подгружать куски функциональностей приложения.
Caching files with Service workers позволяет кешировать файлы в браузере и не загружать их каждый раз с сервера. Возможно, единственный способ сделать офлайн-режим в браузерном приложении.
HTTP Caching — с помощью некоторых HTTP-заголовков можно сильно улучшить скорость загрузки страниц и снизить нагрузку на сервер.
10 быстрых способов улучшения быстродействия компьютера
Как и с обычными проблемами с ПК, не бойтесь перезагрузить систему, если что-то работает не должным образом. Данная простая мера позволит решить целый ряд проблем гораздо быстрее, чем при самостоятельном исследовании и попытках устранить проблему.
Найдите ресурсоемкие программы
Ваш ПК работает медленно, если что-то интенсивно использует его ресурсы. Если замедление произошло очень резко, какой-то беглый процесс может использовать 99 процентов ресурсов процессора, например. Возможен вариант, когда приложение испытывает утечку памяти и использует большое количество памяти, вынуждая систему перейти на дисковый файл подкачки. С другой стороны, приложение может активно использовать диск, вызывая замедление работы других программ, которые также выполняют файловые операции с диском.
Чтобы обнаружить ресурсоемкие приложения, откройте Диспетчер задач. Вы можете нажать правой кнопкой мыши по панели задач и выбрать пункт “Диспетчер задач” или нажать клавиатурное сочетание Ctrl+Shift+Escape. В ОС Windows 8, 8.1 и 10, новый Диспетчер задач имеет обновленный графический интерфейс, в котором приложения, потребляющие большое количество ресурсов, выделяются цветом. Кликните по заголовкам “ЦП”, “Память”, “Диск” для сортировки списка приложений по критериям потребления соответствующих ресурсов. Если какое-либо приложение использует слишком большое количество ресурсов, Вы можете попытаться закрыть их обычным способом, но, если данные попытки безуспешны, выберите нужное приложение и нажмите “Снять задачу” в его контекстном меню.
Закройте программы в системном трее
Многие приложения работают в фоновом режиме, а их иконки отображаются при этом в системном трее или, что то же самое, в области уведомления панели задач. Эти программы как правило запускаются при старте системы и продолжают работать в фоновом режиме, а их значки могут быть скрыты в дополнительном окошке, вызываемом при нажатии на стрелочку в нижнем правом углу экрана. Нажмите на стрелку рядом с системным треем, нажмите правой кнопки мыши по неиспользуемым в данный момент приложениям и выберите пункт “Закрыть” для освобождения ресурсов.
Отключите программы в автозагрузке
Еще эффективнее предотвратить автозапуск приложений при загрузке системы для сохранения памяти и ресурсов процессора, ускоряя при этом процесс авторизации в системе.
В Windows 8, 8.1 и 10 появился собственный Менеджер Автозагрузки, встроенный в Диспетчер задач. Нажмите правой кнопкой мыши по панели задач и выберите пункт “Диспетчер задач” или нажмите клавиатурное сочетание Ctrl+Shift+Escape. Перейдите на вкладку “Автозагрузка” и отключите приложения, которые Вы не используете. Windows любезно подскажет, какие приложения больше всего замедляют процесс загрузки компьютера.
Отключите визуальные эффекты
Пользователи Windows используют большое количество анимаций, которые делают компьютер медленнее. Например, Windows может мгновенно скрывать и открывать окна при отключении анимационных эффектов.
Для отключения анимаций, нажмите сочетание клавиша Windows + X или кликните правой кнопкой мыши по кнопки меню Пуск и выберите пункт “Система”. Затем нажмите ссылку “Дополнительные параметры системы” и кликните по кнопке “Параметры” в секции “Быстродействие”. Затем выберите опцию “Обеспечить наилучшее быстродействие” для отключения анимаций или опцию “Особые эффекты” для ручной настройки нужных эффектов. Например, отключите “Анимация окон при свертывании и развертывании” для мгновенного скрытия и открытия окон.
Отключите лишние расширения браузера
Перейдите на страницу со списком установленных расширений браузера и удалите плагины, которые Вы не используете. Также рассмотрите необходимость запуска расширений для воспроизведения необязательного контента. Так, например, предотвратив отображение Flash-содержимого, Вы можете серьезно сэкономить ресурсы ЦП.
Проверьте систему на предмет вредоносных программ и рекламного ПО
Всегда есть вероятность, что компьютер медленно работает из-за активной вредоносной программы, которая работает в фоновом режиме. Причиной снижения производительности может стать не классическая вредоносная программа, а рекламное ПО, которое взаимодействует с браузером и отслеживает пользовательскую активность, добавляя к примеру рекламные объявления.
Для максимальной безопасности просканируйте компьютер антивирусной программой. Для этих целей можно использовать бесплатный сканер Malwarebytes Anti-Malware, которые обнаруживает большинство потенциально нежелательных программ, игнорируемых другими антивирусными решениями. Данные виды угроз обычно проникают на компьютер при установке другого ПО, чтобы предупредить их установку можно воспользоваться утилитой Unchecky.
Освободите дисковое пространство
Выполните дефрагментацию жесткого диска
Дефрагментация жесткого диска не имеет особого смысла на современных системах Windows. Новые ОС автоматически дефрагментируют механические жесткие диски в фоновом режиме. Твердотельные накопители или SSD-диски вообще не нуждаются в дефрагментации, хотя современные Windows умеют оптимизировать и их.
Удалите неиспользуемые программы
Восстановите исходное состояние компьютера или переустановите Windows
На современных системах Windows 8, 8.1 и 10 получить исходное состояние системы очень просто. Вам не нужно использовать установочный носитель системы и переустанавливать Windows. Вместо этого Вы можете использовать опцию восстановления системы в исходное состояние, встроенную в систему. Эта операция схожа с переустановкой Windows и во время нее выполнения будут удалены все установленные программы и системные настройки, хотя персональные файлы могут быть сохранены.
Анализ производительности программного обеспечения при помощи математического планирования эксперимента
«Преждевременная оптимизация есть корень всех зол»
Энтони Хоар
Приветствую всех пользователей Хабра!
Данная статья возникла как полезный побочный продукт моих научных изысканий. Буду рад, если идеи, изложенные ниже, покажутся для вас интересными и полезными, а еще лучше, если получат своё применение и дальнейшее развитие в реально существующих проектах.
Этап 1. Анализ априорной информации.
Факторы с самыми большими значениями будут наибольшим образом влиять на выходную характеристику.
Этап 2. Выбор влияющих факторов.
В таблице 1 представлен набор влияющих факторов, выбранных в результате анализа априорной информации о ПО.
Этап 3. Выбор верхнего и нижнего уровня для факторов.
Этап 4. Составление матрицы планирования и проведение экспериментов.
В таблице 3 представлены результаты проведения серии экспериментов.
Таблица 3.
№ | y | № | y | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | -1 | -1 | -1 | -1 | -1 | 6,909456902 | 17 | +1 | -1 | -1 | -1 | -1 | 6,956250343 |
2 | -1 | -1 | -1 | -1 | +1 | 6,265920885 | 18 | +1 | -1 | -1 | -1 | +1 | 6,27117213 |
3 | -1 | -1 | -1 | +1 | -1 | 1,046864681 | 19 | +1 | -1 | -1 | +1 | -1 | 1,049605346 |
4 | -1 | -1 | -1 | +1 | +1 | 0,959287777 | 20 | +1 | -1 | -1 | +1 | +1 | 0,960128005 |
5 | -1 | -1 | +1 | -1 | -1 | 6,922491238 | 21 | +1 | -1 | +1 | -1 | -1 | 6,94905457 |
6 | -1 | -1 | +1 | -1 | +1 | 6,292138541 | 22 | +1 | -1 | +1 | -1 | +1 | 6,288483698 |
7 | -1 | -1 | +1 | +1 | -1 | 1,047327693 | 23 | +1 | -1 | +1 | +1 | -1 | 1,048429732 |
8 | -1 | -1 | +1 | +1 | +1 | 0,959178464 | 24 | +1 | -1 | +1 | +1 | +1 | 0,959984639 |
9 | -1 | +1 | -1 | -1 | -1 | 6,947828159 | 25 | +1 | +1 | -1 | -1 | -1 | 6,944574752 |
10 | -1 | +1 | -1 | -1 | +1 | 6,269961421 | 26 | +1 | +1 | -1 | -1 | +1 | 6,281574535 |
11 | -1 | +1 | -1 | +1 | -1 | 1,047032595 | 27 | +1 | +1 | -1 | +1 | -1 | 1,047937875 |
12 | -1 | +1 | -1 | +1 | +1 | 0,960076244 | 28 | +1 | +1 | -1 | +1 | +1 | 0,960813348 |
13 | -1 | +1 | +1 | -1 | -1 | 6,954160943 | 29 | +1 | +1 | +1 | -1 | -1 | 6,952602925 |
14 | -1 | +1 | +1 | -1 | +1 | 6,278223336 | 30 | +1 | +1 | +1 | -1 | +1 | 6,284795263 |
15 | -1 | +1 | +1 | +1 | -1 | 1,048019483 | 31 | +1 | +1 | +1 | +1 | -1 | 1,047952991 |
16 | -1 | +1 | +1 | +1 | +1 | 0,960559206 | 32 | +1 | +1 | +1 | +1 | +1 | 0,960591927 |
Этап 5. Анализ результатов.
Коэффициенты уравнения регрессии (3) могут быть найдены как
. (4)
Результаты представлены в таблице 4 и на рис. 2.
Таблица 4.
3,97361211 | 0,0519711 | 0,0245041 | 0,0034686 | -2,9182692 | -0,2483070 |
Рис. 2. Коэффициенты уравнения регрессии.
Этап 6. Вывод.
Из рис. 2 видно, что основной вклад в время генерации web-страницы вносит фактор , характеризующий кэширование данных в приложении. Отрицательное значение коэффициента регрессии означает, что данный параметр уменьшает функцию отклика черного ящика. В нашем примере это означает уменьшение времени генерации страницы.
Строго говоря, такие результаты являются очевидными, так как включение кэширования данных приложением влечет за собой минимальное число запросов к СУБД. Таким образом, влияние параметров настройки СУБД становится несущественным. Полученные результаты подтверждают возможность использования МПЭ применительно к анализу производительности ПО.
В данной статье я попытался рассмотреть возможность применения существующего уже давно метода математического планирования эксперимента применительно к анализу производительности ПО. Такой подход позволяет преодолеть ряд трудностей, возникающих при анализе программных систем, выявить факторы, наиболее сильно влияющие на анализируемую характеристику, выявить зависимости между факторами.
Разумеется, представленная методология не претендует на замену существующих методов анализа производительности, например, профилирования. Однако существует ряд задач, в которых применение подобной техники способно существенно облегчить задачи исследователя.