Light-electric.com

IT Журнал
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Оптимизация программного обеспечения

Тема 2.8. Оптимизация программ. Оптимизирующие компиляторы

Понятие оптимизации программ

Оптимизация программы — это улучшение какой-либо характеристики программы, называемой критерием оптимизации. Оптимизация программ в основном выполняется по двум основным критериям: быстродействие и объему используемых данных.

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

Основная цель профилировки – это исследование характера поведения приложения во всех его точках. В зависимости от степени детализации в качестве «точки» рассматривается как отдельная машинная команда, так и целая конструкция высокого языка — функция, цикл, процедура. Сложная программа состоит из большого числа функций. Нет смысла оптимизировать их все – трудоемкость такого подхода будет выше выгод, полученных от оптимизации программы целиком. Для начала необходимо локализовать участки кода с максимальной вычислительной трудоемкостью. Участки программы, которые в наибольшей степени влияют на ее производительность, в силу наиболее частого выполнения или своей ресурсоемкости называются критическим кодом. В поиске критического кода программы используют профайлеры (профилировщики) – специальные программы, которые измеряют временные затраты на выполнение участков кода программы. Профилировщики представляют возможности для оптимизации программ. К таким программам относятся Intel VTune, AMD Code Analyst, profile.exe и множество других. Наиболее мощным из них на сегодняшний день является пакет от Intel. Эта программа позволяет измерить время обработки каждой команды и вывести полную статистику о состоянии процессора при выполнении каждой команды.

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

• определение общего времени исполнения каждой точки программы;

• определение удельного времени исполнения каждой точки программы;

• определение причины и/или источника конфликтов;

• определение количества вызовов той или иной точки программы;

• определение степени покрытия программы.

Основные правила оптимизации:

1. Прежде чем приступать к оптимизации, необходимо иметь надежно работающий неоптимизированный вариант.

2. Основной прирост оптимизации дает не учет особенностей системы, а алгоритмическая оптимизация.

3. Обнаружив профилировщиком узкие места необходимо произвести оптимизацию в рамках языка высокого уровня.

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

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

Проводя оптимизацию, не следует забывать о ее цели. Фактически идеал недостижим, поэтому оптимизацию следует завершать когда:

1. Производительность программы признана удовлетворяющей;

2. В программе отсутствуют «горячие точки», то есть количество инструкций равномерно распределено по все программе, и дальнейшая оптимизация потребует переписывания большого количества кода;

3. Сложность алгоритма настолько высока, что не представляется возможным дальнейшая оптимизация без значительных временных затрат;

4. Критическая зависимость от платформы, когда дальнейшая машинно-зависимая оптимизация приведет к потере совместимости с одной из целевых платформ.

Ко всем методам оптимизации алгоритма предъявляются следующие требования:

1. оптимизация должна быть по возможности максимально машинно- независимой и переносимой на другие платформы (операционные системы) без существенных потерь эффективности.

2. оптимизация не должна увеличивать трудоемкость разработки (в том числе тестирования) приложения более чем на 10-15%.

3. оптимизирующий алгоритм должен давать выигрыш не менее чем на 20-25% в скорости выполнения.

4. оптимизация не должна допускать безболезненное внесение изменений.

Алгоритмические приемы оптимизации

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

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

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

На практике используется весьма широкий набор машинно-независимых оптимизирующих преобразований, что связано с большим разнообразием неоптимальностей. К ним относятся:

• разгрузка участков повторяемости — это такой способ оптимизации, который состоит в вынесении вычислений из многократно исполняемых участков программы на участки программы, редко исполняемые. К этому виду преобразования относятся различные чистки зон, тел циклов и тел рекурсивных процедур, когда инвариантные по результату выполнения выражения, исполняемые при каждом прохождении участка повторяемости, выносятся из него. Если размещение осуществляется перед входом в участок повторяемости, то эту ситуацию называют чисткой вверх, если же за выходом из участка повторяемости, то чисткой вниз

• упрощение действий — этот способ оптимизации ориентирован на улучшение программы за счет замены групп (как правило, удаленных друг от друга) вычислений на группу вычислений, дающий тот же результат с точки зрения всей программы, но имеющих меньшую сложность.

• чистка программы — данный способ повышает качество программы за счет удаления из нее ненужных объектов и конструкций. Набор преобразований этого типа включает в себя следующие оптимизации: удаление идентичных операторов, удаление из программы операторов, недостижимых по управлению от начального, удаление несущественных операторов, то есть операторов не влияющих на результат программы, удаление процедур, к которым нет обращений, удаление неиспользуемых переменных и другие.

• экономия памяти и оптимизация работы с памятью — улучшения быстродействия возможно за счет уменьшения объема памяти, отводимой под информационные объекты программы в каждом ее исполнении.

• реализация действий — это способ повышения быстродействия программы за счет выполнения определенных ее вычислений на этапе трансляции.

• сокращение программы и другие методы.

Машинно-зависимые приемы оптимизации

Машинно-зависимые используют особенности устройства и работы конкретной системы. Ярким примером машинно-зависимой оптимизации является векторизация операций, т.е. использование потоковых расширений процессора, таких как MMX (MultiMedia eXtensions), SSE (Streaming SIMD Extensions) и т.п. Машино-зависимую оптимизацию можно выполнять двумя различными способами. Первый способ основан на понимании работы кодогенератора компилятора, его алгоритма и рекомендуется для приложений, в которых компилятор выбирается в начале проекта и в дальнейшем не меняется. При использовании такого способа преобразуется исходный код программы, написанный на языке высокого уровня. Для тех проектов, в которых заранее не известен компилятор (OpenSource проекты, кроссплатформенные приложения) применятся другой способ, основанный на замещении ресурсоемких участков кода ассемблерными вставками. При такой оптимизации ухудшается переносимость кода на другие платформы. Машинно-зависимые способы оптимизации довольно хорошо автоматизируются и большую часть их выполняют оптимизирующие компиляторы. Однако всегда остаются моменты в программе, которые можно оптимизировать вручную.

Оптимизация

Оптимизация

Под оптимизацией понимают последовательность эквивалентных преобразований исходной программы, уменьшающих ее стоимость . Как набор, так и порядок выполнения этих преобразований зависят от того, что считается стоимостью программы. В качестве такой стоимости могут выступать, например, среднее время работы, объем кода и т.д. Эффективность оптимизации также зависит от отношения эквивалентности и от размера участка экономии, на котором эта оптимизация проводится (обычно оптимизированной программе разрешается иметь большую область определения , чем исходной). За счет оптимизации невозможно добиться существенного улучшения алгоритма программы, можно только говорить об улучшении реализации этого алгоритма. В удачных случаях оптимизация может ускорить программу в несколько раз. Полезность применения оптимизации обусловлена следующими причинами:

  • Распространением языков сверхвысокого уровня, языков спецификации и систем проектирования. Как правило, подобные системы порождают программы на некотором языке высокого уровня. В этом случае оптимизация может нейтрализовать избыточность такого порождения, приблизив качество сгенерированной программы к ручному программированию.
  • Необходимостью поддержки и сопровождения готовой программы. Такие требования зачастую приводят к тому, что программисты используют не самые эффективные решения в целях улучшения наглядности или легкости сопровождения программ (очень часто соображения эффективности и сопровождаемости противоречат друг другу). В то же время недостатки эффективности могут быть исправлены оптимизатором при генерации окончательной программы.
  • Усилением контроля семантических ошибок. Такие ошибки требуют специального анализа исходной программы, который может являться побочным результатом действий оптимизатора.

Виды оптимизации

Существует много различных классификаций оптимизирующих преобразований. Здесь мы рассмотрим классификации по уровню представления программы и по размеру участка экономии.

В зависимости от уровня представления программы различают следующие виды оптимизации:

  • Оптимизацию на уровне исходного языка. При этом в результате трансформации получается программа, записанная в том же самом языке.
  • Машинно-независимую оптимизацию. В этом случае преобразованию подвергается программа на уровне машинно-независимого промежуточного представления, общего для группы входных или машинных языков.
  • Машинно-зависимую оптимизацию, то есть оптимизацию на уровне машинного языка.

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

Читать еще:  Потоковая оптимизация nvidia что это

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

Записки программиста

Двенадцать эффективных методов оптимизации программ

Программисты постоянно занимаются оптимизацией программ. Это такая же неотъемлемая часть работы, как исправление багов или рефакторинг. Обычно, говоря «оптимизация», мы имеем в виду ускорение программы. Несмотря на то, что под оптимизацией также может пониматься уменьшение объема используемой оперативной памяти или иных ресурсов (скажем, сетевого трафика или заряда батареи), в данной заметке речь пойдет именно об ускорении.

Для начала, немного прописных истин. Никто не занимается оптимизацией до тех пор, пока не придет заказчик (или коллега из отдела QA — не суть важно) и не скажет, что в таком-то месте программа работает слишком медленно. То есть, в первую очередь мы пишем программу с простым и понятным кодом, как следует тестируем ее и только потом, если понадобится, оптимизируем. Нет смысла оптимизировать программу, если (1) все работает и все довольны, (2) через полгода требования к программе поменяются и код придется переписать.

Примечание: Пожалуй, если вы пишите библиотеку, то позаботиться об ее оптимизации можно и заранее.

Также никто не бросается оптимизировать программу до тех пор, пока не станет понятно, насколько быстро она должна работать. Формулировка «таблица должна отрисовываться не дольше, чем за одну секунду» является правильной, а «таблица должна отрисовываться быстро» — нет. То есть, вы должны знать, в каком случае считать работу выполненной. Нельзя достичь цели, которая постоянно меняется. (Но если бизнес не хочет этого понимать, что ж… любой каприз за ваши деньги.)

Взявшись за оптимизацию, мы находим самое-самое тормозное место и ускоряем его. Если теперь программа работает достаточно быстро и ничего не сломалось, цель достигнута. Иначе переходим к первому шагу. Искать медленные места можно, к примеру, с помощью профилировщика (см perf, bcc/eBPF), сбора метрик, отладочного вывода с временными метками или логирования медленных SQL-запросов. Можно, конечно, и наугад, если в вашем распоряжении много времени.

Теперь перейдем непосредственно к методам. Я подозреваю, что некоторые из них вызовут у вас удивление, тем не менее…

Обновление ПО. Это может показаться невероятным, однако переход на последнюю версию какой-нибудь используемой в проекте библиотеки, СУБД, виртуальной машины Erlang‘а или ядра Linux может очень существенно увеличить скорость работы вашего приложения. Простое и, как правило, быстрое решение.

Настройка окружения. Используемая СУБД или операционная система могут быть настроены неправильно. Настройки по умолчанию MySQL и PostgreSQL предполагают, что вы пытаетесь запустить СУБД на первопне. Один мой коллега рассказывал, как однажды в его практике приложение удалось существенно ускорить, просто попробовав различные параметры JVM. Этот метод даже проще, чем обновление ПО. Однако применять его, по понятным причинам, нужно после обновления. Или в случае, если обновление по каким-то причинам в обозримом будущем невозможно.

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

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

Мемоизация и кэширование. Теперь перейдем к «настоящим» оптимизациям. Мемоизация — это сохранение значения, возвращаемого функцией для заданных аргументов. Кэширование — это сохранение результатов чего угодно. Например, кэшироваться могут веб-страницы или отчеты за месяц. Кэширование может быть неприменимо, если кэшируемые данные быстро обновляются. Также в контексте кэширования часто встает проблема инвалидации кэша. В контексте мемоизации такая проблема не возникает, так как мемоизации обычно подвергаются чистые функции, то есть, функции без побочных эффектов, возвращаемое значение которых зависит только от аргументов. Мемоизация и кэширование эффективны и легко реализуются, однако неправильное кэширование может препятствовать горизонтальному масштабированию программы. При добавлении в ваше приложение очередного кэша, подумайте о том, как вы будете им управлять, когда программа будет работать в двух и более экземплярах.

Распараллеливание. Распараллеливание может быть простой или сложной операцией, в зависимости от. Например, в Erlang очень многие задачи могут быть с легкостью распараллелены путем написания буквально десятка строк кода. А в Scala вы можете без особого труда воспользоваться параллельными коллекциями вместо обычных. Однако некоторые задачи не могут быть решены параллельно по своей природе. И если программа работает на одноядерном процессоре, распараллеливание ничего не даст. Недетерминированные функции и функции с побочными эффектами усложняют применение этой оптимизации, что есть еще один повод для написания чистых функций. При написании веба или каких-то бэкендов распараллеливание не всегда возможно, так как нельзя занять все ядра обработкой запроса одного пользователя, заблокировав тем самым обработку остальных запросов.

Распределение нагрузки. Если нагрузка на СУБД мала, можно воспользоваться триггерами или хранимками, разгрузив тем самым само приложение и уменьшив трафик. Или, наоборот, можно перенести всю логику в приложение, разгрузив СУБД. Для построения отчетов, создания резервных копий и выполнения других тяжелых операций над СУБД имеет смысл завести специальную реплику. СУБД можно настроить так, чтобы разные таблицы хранились на разных физических дисках. Можно отдать пользователю статическую страницу с JavaScript и общаться с ним исключительно при помощи REST API. Пусть сам генерирует себе HTML. Статический контент можно держать на отдельном домене. Этим вы уменьшите трафик, так как на этот домен не будут отправляться кукисы. Незачем gzip’овать/шифровать данные в Apache или даже в самом приложении, если с этой задачей намного лучше справится nginx. При помощи шардинга можно распределить нагрузку между несколькими репликами базы данных, процессами Erlang’а или экземплярами Memcached.

Ленивые вычисления. Грубо говоря, ленивые вычисления — это когда вместо конкретного значения возвращается анонимная функция, которая при вызове вычисляет это значение. В ряде языков программирования ленивые вычисления поддерживаются на уровне синтаксиса. Фокус в том, чтобы значение было вычислено непосредственно перед его использованием. Представьте себе ситуацию, когда мы отдаем данные в формате CSV и пользователь может задать фильтр, определяющий, какие столбцы должны быть переданы. В этом случае ленивые вычисления оказываются как нельзя кстати. Если окажется, что значение на самом деле не нужно, мы сэкономим время, которое было бы потрачено на его вычисление. Однако следует отметить, что ленивые вычисления приводят к увеличению объема используемой памяти и могут плохо работать с грязными функциями.

Отложенные расчеты. Зачем считать что-то прямо сейчас, если это можно сделать потом? При обработке HTTP-запроса мы можем моментально вернуть пользователю OK, а непосредственную работу выполнить в фоновом процессе. Если запрос очень важен, мы можем положить его в персистентную очередь задач, обрабатываемую по cron’у. Или группой непрерывно работающих процессов. В последнем случае мы даже имеем хорошие шансы получить горизонтальное масштабирование и, соответственно, реальное увеличение скорости, а не только видимое. Кроме того, отложенные задачи могут быть похожи. Например, им нужны одни и те же данные из БД. В этом случае при отложенной обработке N задач одной пачкой можно сходить в базу в N раз меньше раз.

Более подходящие алгоритмы и структуры данных. Quicksort быстрее сортировки пузырьком, а эллиптические кривые быстрее RSA. Если нужно проверить принадлежность элемента множеству, следует использовать хэш-таблицы , а не односвязные списки. Правильные индексы и денормализация схемы базы данных могут существенно сократить время выполнения SQL-запросов. Если требуется синхронизировать некие данные, вместо полной их пересылки при каждом изменении лучше использовать схему снапшот + апдейты.

Аппроксимация. Это почти что случай более подходящего алгоритма, только с потерей точности. Вместо длинной арифметики часто можно обойтись обычными float’ами. При сборе статистики данные можно слать по UDP вместо TCP. Пусть небольшая часть пакетов не дойдет, а часть — придет дважды. При сборе статистики намного важнее изменение цифр, а не конкретные значения. Также, например, незачем строить график по всем точкам, если можно взять их подмножество и построить кривую Безье. Вместо дорогостоящего вычисления медианы часто можно посчитать среднее.

Переписывание на другой язык. Вполне может оказаться, что программу в существенной степени тормозит сборка мусора или, скажем, проверка типов на этапе выполнения. Переписывание небольших частей программы с Ruby на Scala или с Erlang на OCaml может привести к ускорению этой программы. Если переписываемый кусок кода достаточно прост, можно с небольшим риском переписать его на Си или C++. Этот метод нужно использовать крайне осторожно. Он приводит к появлению зоопарка языков программирования, что усложняет поддержку проекта. Метод может не сработать, например, из-за накладных расходов на преобразование данных из одного представления в другое. Также он может быть опасен. Например, ошибка в NIF может привести к падению всей виртуальной машины Erlang’а, а не одного процесса.

Читать еще:  Скачать программу оптимизатор

В заключение хочу отметить, что приведенная классификация весьма и весьма условна. Совершенно очевидно, что граница между распараллеливанием и распределением нагрузки или отложенными расчетами и ленивыми вычислениями весьма размыта.

Оптимизация

Оптимизация, все всяких сомнений, является неотъемлемой частью разработки практически любой программы. Если ваша программа хорошо делает то, для чего она предназначена – это хорошо, но если она ещё делает это быстро, т.е. программа оптимизирована – то это вдвойне хорошая программа. Но, при этом, следует чётко понимать, когда необходимо заниматься оптимизацией, а когда оптимизация превращается в пустую трату времени. Я почти в каждом уроке пишу о том, что я не сторонник ранней оптимизации ПО, но всё равно читатели блога часто мне пишут о том, что им хотелось бы, что бы я рассматривал и вопросы ускорения работы программ, рассказал о тонкостях этого непростого дела и дал хотя бы общие рекомендации. В общем, я решил удовлетворить эти просьбы и немного рассказать о том, как я лично делаю оптимизацию, когда я её делаю и почему я это делаю. А так же о том, как не потерпеть крах и не потратить время впустую, напоровшись на подводные камни.

Оптимизировать надо то, что тормозит

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

Профайлинг – ключ к успешной оптимизации

Что бы начинать оптимизацию программы, прежде всего необходимо понять, какие именно участки кода создают не нужные “тормоза” – как правило “тормозит” от 1% до 5% кода, весь остальной код просто не оказывает никакого влияния на производительность. Проще всего найти эти участки кода запустив профайлер. Проще всего использовать встроенный в Visual Studio, либо Intel Perfomance Analyzer. Как правило, достаточно 1 раз запустить вашу программу под профайлером и заставить её поработать от нескольких секунд до нескольких минут, а потом просто посмотреть отчёт, сформированный профайлером. Из этого отчёта Вам понадобится лишь несколько первых строк, в которых и находятся те самые участки программы (функции), которые занимают больше всего процессорного времени – именно их и надо оптимизировать в первую очередь. И лишь после того, как Вы это сделаете, надо судить о том, стоит ли продолжать процесс оптимизации или уже пора остановиться – незачем тратить часы и дни работы на то, что бы, например, поднять ФПС игры с 90 до 91 кадра в секунду.

Методы оптимизации

Существую несколько достаточно простых правил, которые позволяют ускорить работу вашей программы, т.е. прооптимизировать её. Как правило, это следующие методы:

  • Локализация данных
  • Векторизация
  • Минимизация вызова функций
  • Инлайн-функции

Оптимизация через локализацию данных

Как известно, CPU обычно имеет внутри себя от одного до нескольких уровней кешей – с ними процессор работает намного (в разы/десятки/сотни раз) быстрее, чем с обычной оперативной памятью. Как только процессор обращается к каким-то данным, которые находятся вне его кеша – он читает эти данные из памяти, располагает их в кеше и потом работает с ними. Работать напрямую с памятью он обычно не умеет. При этом читает он обычно не только те данные, которые ему нужны в данный момент, но и небольшой “запас”, предполагая при этом, что они тоже могут понадобиться. Процесс чтения данных из обычной памяти в кеш не слишком быстрый (если даже не сказать что он очень медленный), а процесс чтения этих данных потом из кеша в процессор – быстрый.

Соответственно, если расположить обрабатываемые данные в памяти таким образом, что бы они, при работе, обрабатывались последовательно, то работа с такими данными может оказаться в сотни раз быстрее, чем при работе с данными, разбросанными по всем концам оперативной памяти.

Соответственно, совет в данном случае очень простой – просто располагайте данные в памяти последовательно. Например, не создавайте сотни объектов через оператор new, а создавайте сразу массив с помощью оператора new[]. Если количество создаваемых объектов велико (сотни, тысячи), то вы можете получить существенный прирост производительности – иногда даже в сотни раз.

Оптимизация через векторизацию

Если ваши данные локализованы в одном участке памяти и вам необходимо обработать массив этих данных, то очень часто может помочь оптимизация через векторизацию. Обычно всё, что требуется с вашей стороны – это включить соответствующие опции компилятора, как правило это: разрешить использовать SSE/SSE2 и указать максимальный уп=ровень оптимизации. После этого, при обработке массивов данных (в цикле), компилятор сам постарается сделать специальный код, которые будет использовать SSE-инструкции для обработки массивов – при больших размерах массива, часто это может привести к ускорению работы программы в несколько раз.

Оптимизация с помощью минимизации вызова функций

Обычно вызов каждой функции требует от центрального процессора поместить данные, передаваемые функции (параметры функции) в “стек”, вызывать функцию и прочитать результат работы функции (возвращаемое значение) из стека. Фактически, вызов каждой, даже самой простой, функции превращается в кучу работы. Соответственно, если Вы, вместо того, что бы вызывать функцию, опишите операции, которые надо провести над данными непосредственно, без вызова функции – скорее всего вы получите прирост производительности. При этом, как правило, такую операцию имеет смысл делать лишь для достаточно небольших функций – размером не больше нескольких (до десяка-двух) строк кода, не более – для более больших функций разница в скорости будет уже практически незаметна. И наоборот – чем меньше функция, тем более заметен будет результат. При этом надо заметить, что часто компилятор (при включённых опциях оптимизации) сам проводит такую оптимизацию и получает хороший код без участия программиста. Но он не всегда может сам до этого догадаться, потому ему иногда надо помогать, просто прооптимизировав код вручную.

Оптимизация с помощью инлайн-функций

Инлайн-функции, это такие функции, которые компилятор пытается встроить непосредственно в код, вместо создания вызова функции. Потому это правило оптимизации является прямым следствием предыдущего. Обычно для того, что бы функция заинлайнилась надо указать при её декларации ключевое слово inline или __inline – и компилятор заинлайнит её, если посчитает это разумным.

Когда не надо оптимизировать программу?

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

Если начать делать оптимизацию до того, как вы завершили основную часть работы над функционалом – очень высока вероятность того, что Вам позже придётся вносить какие-то дополнительные изменения в уже прооптимизированный участок кода, а это приведёт одновременно к тому, что вы будете путаться (читать и понимать оптимизированный код обычно сложнее) и при этом Вам потом ещё придётся повторно проводить оптимизацию (т.к. Вы поменяете код и не факт, что после этого он будет работать так же быстро, как и прежде).

Иными словами, Вы будете делать двойную, тройную, и более, работу – старайтесь оптимизировать не только производительность, но и своё рабочее время – его заменить нечем. Вместо того, что бы “разгонять” совершенно не важный участок программы, возможно, следует заняться более важными вещами – реализацией новых функций, повышением удобства пользовательского интерфейса, поиском багов и т.д.

Именно по этой причине я сам всегда провожу работы по ускорению программы лишь в самую последнюю очередь, чего и Вам советую

Кстати, после оптимизации обязательно не забудьте ещё раз протестировать ваш исходный код на предмет отсутствия багов – очень часто даже опытные программисты, в погоне за производительностью, допускают много мелких и сложнонаходимых ошибок – будьте внимательны!

P/S Как-нибудь я постараюсь найти время и рассказать и показать на примерах различные виды оптимизаций, в том числе не только самого кода, но и графики, чтения с дисков и прочего.

Какие бесплатные инструменты для оптимизации рабочего процесса используют эксперты

  • Ответы экспертов, 17 ноября 2018 в 18:54
  • Анастасия Витвицкая

Можно вести записи в настольном блокноте, писать код в блокноте Windows, а для того, чтобы ничего не забывать, клеить стикеры на монитор. Однако работа при этом будет выполняться, мягко говоря, не очень эффективно. Оптимизировать рабочий процесс помогают сотни и тысячи различных сервисов. Но найти действительно толковые и полезные приложения и сайты очень сложно, а если и есть что-то подходящее, то почти всегда за платную подписку. Наш читатель устал от этого многообразия и обратился к нам за советом:

«Какие бесплатные инструменты помогают оптимизировать рабочий процесс?»

За разъяснениями мы обратились к нашим экспертам, а полученные ответы предоставляем вашему вниманию. В конце статьи найдёте список всех упомянутых инструментов, разбитый по их предназначению.

Павел Романченко , технический директор центра инновационных технологий и решений «Инфосистемы Джет»

Процесс разработки включает в себя не только кодинг, но и множество вспомогательных задач. Поэтому, помимо IDE и стандартных инструментов Java (например, Apache Maven), я использую довольно незамысловатый набор программ: консоль Konsole, командную оболочку zsh, лучший редактор Vim, язык AWK для обработки логов и различных файлов, Zim — для заметок.

Кирилл Меженцев , программист группы разработки карты рассрочки «Совесть»

Оптимизировать рабочий процесс мне помогают следующие инструменты:

1. Плагин SonarLint к IntelliJ IDEA — помогает отлавливать старые и новые баги, заставляет писать лучше и не пропускать свои же //todo.
2. Microsoft To-Do — очень удобно составлять списки текущих задач, а потом приоритизировать из них задачи на день. Почти как персональный спринт. Если какие-то задачи на день не выполнены, сервис предложит их решить в первую очередь на следующий день.
3. Trello — сборник идей, Long-Term планов. Удобно следить за задачами по статусам и дедлайнам. Можно сделать отдельную доску для отпуска, петпроджекта или очереди технологий на изучение.
4. Raindrop.io — сервис закладок. Удобно сохранять статьи на потом. Ссылки хранятся по спискам. Когда нет времени, добавляю статью в список «прочитать», после прочтения либо удаляю, либо добавляю в тематический список полезных ссылок.
5. Siri Shortcut — пользуюсь удобным шорткатом, который по голосовой команде или нажатию показывает программу ближайшей встречи.

Антон Попович , сооснователь и технический директор, HINT Lab

Свой процесс управления рабочим (да и личным) временем я построил на использовании ряда инструментов, все из которых позволяют получить от них достаточную пользу, не переходя на платные тарифы:
1. Flying Logic — для целеполагания.
2. Asana — для ведения списка дел, выполнение которых не привязано к определëнному моменту времени.
3. Google.Календарь — для управления делами, выполнение которых привязано к определëнному моменту времени.
4. Toggl — для анализа, на что я трачу своë время, чтобы затем оптимизировать его в соответствии с принципом Парето.

Евгения Перебейносова , Head of SEO, Racurs

Мой топ занимают:
• Аrsenkin Tools — инструменты и букмарклеты, которые значительно упрощают 80 % рутинных задач SEO-специалиста от парсинга тегов и метаданных конкурентов до быстрого анализа оптимизации конкретного url. При этом визуализация проста и приятна глазу, а скорость и легкость использования впечатляют.
• бесплатные инструменты Пиксель Тулс — мы используем и экспертные сервисы, и те, что не требуют подписки. Поиск поддоменов и зеркал, проверки сайта на санкции и фильтры, парсинг поисковых подсказок, а также широкую функциональность подготовки и проверки текстового контента – вот, что может помочь в ежедневной работе спеца.
• RDS bar — плагин для экспресс-анализа сайта, ставший уже классикой и неотъемлемым атрибутом любого набора плагинов для SEO.
• SEO META in 1 CLICK — компактное и удобное представление сводной информации об оптимизации конкретной страницы.
• Плагин Яндекс.Метрики для вашего браузера — работает как набор горячих клавиш для быстрого перехода к счётчику, карте кликов, ссылок и аналитике форм.
• Плагин SimilarWeb отлично справится с показом статистики посещаемости вашего сайта и, что гораздо важнее, сайта конкурента.
• Плагин Web Developer удобен для технического анализа сайта.
• Ну и, конечно, бесплатные «скриншотеры», Punto Switcher, анонимайзеры и другие похожие программы, что уже относится к общему офисному софту, безотносительно профессиональной специфики.

Владислав Галицкий , продуктовый менеджер в команде BI Connect, OWOX BI

1. Atom — бесплатный текстовый редактор с открытым исходным кодом для Linux, macOS и Windows. Поддерживает плагины, написанные на Node.js и встраиваемые под управлением Git. Большинство плагинов имеют статус свободного программного обеспечения, разрабатываются и поддерживаются сообществом.
Преимущества:
– удобный текстовый редактор;
– отличная интеграция с репозиторием;
– поддерживает большое количество плагинов;
– поддерживает обширное количество языков программирования.

2. Emmet — набор плагинов для текстовых редакторов, которые в разы ускоряют написание кода HTML, XML, XSL, а также кода на некоторых других языках.
Преимущества:
– универсальный плагин для текстового редактора;
– в несколько раз увеличивает скорость написания кода;
– входит в некоторые современные текстовые редакторы по умолчанию;
– простой и понятный в использовании.

3. Figma — кросс-платформенный сервис для дизайнеров, который позволяет нескольким людям в режиме реального времени работать над одним и тем же проектом. В последнее время расплодилось бесчисленное множество графических онлайн-редакторов, но используем Figma из-за ряда преимуществ:
– поддержка практически всех форматов изображений;
– автоматическое формирование CSS стилей;
– удобная коммуникация с дизайнером;
– оптимизация процесса вёрстки макетов;
– поддержка большинства форматов графических инструментов.

Александр Янес , директор по развитию Девайс Консалтинг

Раньше блокнот и календарь на телефоне, сейчас ещё пользуюсь Trello. В этом приложении прописываю свои личные списки дел по разным категориям (от списка досуга и дел по здоровью до списка рабочих дел, необходимых покупок, желаний, путешествий), и с коллегами ведём общие списки дел. Кроме просто записей, важна постановка целей и фокусировка на необходимых задачах, чтобы не было распыления. В воскресенье готовлю себе «расписание» на неделю вперед, в котором учитываю, в том числе и свои регулярные дела (в том числе и чтение различной литературы), и дела которые уже запланированы, выделяю время на досуг и, разумеется, время на вдруг появившиеся задачи. А так как есть фокусировка на цели, то в «свободное» рабочее время всегда понятно, чем заняться.

Александр Завьялов , SEO-специалист, Racurs

Вот те программы, которыми я пользуюсь каждый день:
• tools.promosite – анализатор апдейтов Яндекса, индикатор апов индекса (текстовых), ссылочных апдейтов, тИЦ, сохранённой копии, подкрутки алгоритма и выдачи Яндекса. Похожих сервисов много, но этим пользуемся так как он уже давно в закладках.
• Bertal – сервис для проверки http заголовков сайта и просмотра html кода интернет страниц, который получает бот — всё сразу и в одном месте.
• Internet Archive: Wayback Machine – сервис, позволяющий увидеть прошлую историю сайта (как менялся сайт, какие правки вносились по тексту). Полезен не только SEO-специалистам, но и интернет-маркетологам.
• Text.ru — онлайн-инструмент для проверки уникальности и качества текста. Его плюс в доступности — он бесплатный, можно проверить текст без регистрации, посмотреть плотность по ключам и остальные характеристики.
• Google PageSpeed Insights — инструмент, позволяющий увидеть скорость загрузки страницы вместе с рекомендациями по улучшению производительности веб-сайта. Много про него скепсиса, но иногда и там можно найти полезные рекомендации, самое главное знать, что именно рекомендуется в сервисе.
• Google Search Console и Яндекс.Вебмастер – незаменимые инструменты для оценки всей информации о сайте, которую знают поисковые системы (Google и Яндекс соответственно): запросы, ссылки, страницы, ошибки и так далее.
• Яндекс.Метрика и Google Аnalytics — рабочие инструменты для сбора детальной статистики посетителей веб-сайтов в Яндексе и Google.
• Google Таблицы — лучший инструмент для быстрой работы с данными, кроме табличных функций, есть много дополнительных плагинов для ускорения работы. Главные особенности — это возможность писать свои скрипты и возможность импорта данных со страниц сайтов.

Али Рагимов , главный специалист отдела разработки программного обеспечения, Okko

Когда работаешь за компьютером, постоянно что-то отвлекает: мессенджеры, почта. Невовремя вспоминаешь, что хотел что-то посмотреть в интернете. В такие моменты производительность, разумеется, падает очень сильно. Для того, чтобы вернуть фокус на работу, я использую технику «Pomodoro». Эта техника подразумевает собой небольшие итерации работы, сменяемые короткими паузами. То есть работаешь 25 минут, отдыхаешь 5 и после нескольких таких повторений – отдых 15 минут. Во время работы запрещено отвлекаться на что-либо, а во время отдыха наоборот – заниматься какими-либо делами (или даже думать о них!). Когда есть строгие рамки, контролировать себя проще. Для этой техники есть множество приложений под любые ОС. Я, например, использую Focus 10 на Windows, Tomighty на Ubuntu и Pomodoro Timer Lite на Android.

Если я работаю над большой задачей, то я декомпозирую её, а получившиеся подзадачи ставлю в порядке, в котором буду выполнять. На каждую «помидору» беру одну или две подзадачи. Для ведения списка задач отлично подойдут такие приложения, как Wunderlist или Microsoft To-Do. В них для больших задач можно создавать списки, а как элементы этих списков – декомпозированные таски. Таким образом, всегда наглядно видишь, сколько сделано, а сколько осталось. А после выполнения всех задач в списке его можно с чистой совестью удалить.

Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector
×
×