Оптимизация программного кода модуля. Оптимизация кода
Оптимизация кода Википедия
Оптимизация — модификация системы для улучшения её эффективности. Система может быть одиночной компьютерной программой, цифровым устройством, набором компьютеров или даже целой сетью, такой как Интернет.
Хотя целью оптимизации является получение оптимальной системы, истинно оптимальная система в процессе оптимизации достигается далеко не всегда. Оптимизированная система обычно является оптимальной только для одной задачи или группы пользователей: где-то может быть важнее уменьшение времени, требуемого программе для выполнения работы, даже ценой потребления большего объёма памяти; в приложениях, где важнее память, могут выбираться более медленные алгоритмы с меньшими запросами к памяти.
Более того, зачастую не существует универсального решения (хорошо работающего во всех случаях), поэтому инженеры используют компромиссные (англ. tradeoff) решения для оптимизации только ключевых параметров. К тому же, усилия, требуемые для достижения полностью оптимальной программы, которую невозможно дальше улучшить, практически всегда превышают выгоду, которая может быть от этого получена, поэтому, как правило, процесс оптимизации завершается до того, как достигается полная оптимальность. К счастью, в большинстве случаев даже при этом достигаются заметные улучшения.
Оптимизация должна проводиться с осторожностью. Тони Хоар впервые произнёс, а Дональд Кнут впоследствии часто повторял известное высказывание: «Преждевременная оптимизация — это корень всех бед». Очень важно иметь для начала озвученный алгоритм и работающий прототип.
Основы
Некоторые задачи часто могут быть выполнены более эффективно. Например, программа на языке Си, которая суммирует все целые числа от 1 до N:
int i, sum = 0; for (i = 1; i <= N; i++) sum += i;Подразумевая, что здесь нет переполнения, этот код может быть переписан в следующем виде с помощью соответствующей математической формулы:
int sum = (N * (N+1)) / 2;Понятие «оптимизация» обычно подразумевает, что система сохраняет ту же самую функциональность. Однако, значительное улучшение производительности часто может быть достигнуто и с помощью удаления избыточной функциональности. Например, если допустить, что программе не требуется поддерживать более, чем 100 элементов при вводе, то возможно использовать статическое выделение памяти вместо более медленного динамического.
Компромиссы (tradeoff)
Оптимизация в основном фокусируется на одиночном или повторном времени выполнения, использовании памяти, дискового пространства, пропускной способности или некотором другом ресурсе. Это обычно требует компромиссов — один параметр оптимизируется за счёт других. Например, увеличение размера программного кэша чего-либо улучшает производительность времени выполнения, но также увеличивает потребление памяти. Другие распространённые компромиссы включают прозрачность кода и его выразительность, почти всегда ценой деоптимизации. Сложные специализированные алгоритмы требуют больше усилий по отладке и увеличивают вероятность ошибок.
Различные области
В исследовании операций, оптимизация — это проблема определения входных значений функции, при которых она имеет максимальное или минимальное значение. Иногда на эти значения накладываются ограничения, такая задача известна как ограниченная оптимизация.
В программировании, оптимизация обычно обозначает модификацию кода и его настроек компиляции для данной архитектуры для производства более эффективного ПО.
Типичные проблемы имеют настолько большое количество возможностей, что программисты обычно могут позволить использовать только «достаточно хорошее» решение.
Узкие места
Для оптимизации требуется найти узкое место (англ. bottleneck - бутылочное горлышко): критическую часть кода, которая является основным потребителем необходимого ресурса. Улучшение примерно 20 % кода иногда влечёт за собой изменение 80 % результатов, согласно принципу Парето. Утечка ресурсов (памяти, дескрипторов и т. д.) также может привести к падению скорости выполнения программы. Для поиска таких утечек используются специальные отладочные инструменты, а для обнаружения узких мест применяются программы — профайлеры.
Архитектурный дизайн системы особенно сильно влияет на её производительность. Выбор алгоритма влияет на эффективность больше, чем любой другой элемент дизайна. Более сложные алгоритмы и структуры данных могут хорошо оперировать с большим количеством элементов, в то время как простые алгоритмы подходят для небольших объёмов данных — накладные расходы на инициализацию более сложного алгоритма могут перевесить выгоду от его использования.
Чем больше памяти использует программа, тем быстрее она обычно выполняется. Например, программа-фильтр обычно читает каждую строку, фильтрует и выводит эту строку непосредственно. Поэтому она использует память только для хранения одной строки, но её производительность обычно очень плохая. Производительность может быть значительно улучшена чтением целого файла и записью потом отфильтрованного результата, однако этот метод использует больше памяти. Кэширование результата также эффективно, однако требует большего количества памяти для использования.
Простейшие приёмы оптимизации программ по затратам процессорного времени
Оптимизация по затратам процессорного времени особенно важна для расчетных программ, в которых большой удельный вес имеют математические вычисления. Здесь перечислены некоторые приемы оптимизации, которые может использовать программист при написании исходного текста программы.
Инициализация объектов данных
Во многих программах какую-то часть объектов данных необходимо инициализировать, то есть присвоить им начальные значения. Такое присваивание выполняется либо в самом начале программы, либо, например, в конце цикла. Правильная инициализация объектов позволяет сэкономить драгоценное процессорное время. Так, например, если речь идет об инициализации массивов, использование цикла, скорее всего, будет менее эффективным, чем объявление этого массива прямым присвоением.
Программирование арифметических операций
В том случае, когда значительная часть времени работы программы отводится арифметическим вычислениям, немалые резервы повышения скорости работы программы таятся в правильном программировании арифметических (и логических) выражений. Важно, что различные арифметические операции значительно различаются по быстродействию. В большинстве архитектур, самыми быстрыми являются операции сложения и вычитания. Более медленным является умножение, затем идёт деление. Например, вычисление значения выражения xa{\displaystyle {\frac {x}{a}}}, где a{\displaystyle a} — константа, для аргументов с плавающей точкой производится быстрее в виде x⋅b{\displaystyle x\cdot b}, где b=1a{\displaystyle b={\frac {1}{a}}} — константа, вычисляемая на этапе компиляции программы (фактически медленная операция деления заменяется быстрой операцией умножения). Для целочисленного аргумента x{\displaystyle x} вычисление выражения 2x{\displaystyle 2x} быстрее произвести в виде x+x{\displaystyle x+x} (операция умножения заменяется операцией сложения) или с использованием операции сдвига влево (что обеспечивает выигрыш не на всех процессорах). Подобные оптимизации называются понижением силы операций. Умножение целочисленных аргументов на константу на процессорах семейства x86 может быть эффективно выполнено с использованием ассемблерных команд LEA, SHL и ADD вместо использования команд MUL/IMUL:
Подобные оптимизации являются микроархитектурными и обычно производятся оптимизирующим компилятором прозрачно для программиста.
Относительно много времени тратится на обращение к подпрограммам (передача параметров через стек, сохранение регистров и адреса возврата, вызов конструкторов копирования). Если подпрограмма содержит малое число действий, она может быть реализована подставляемой (англ. inline) — все её операторы копируются в каждое новое место вызова (существует ряд ограничений на inline-подстановки: например, подпрограмма не должна быть рекурсивной). Это ликвидирует накладные расходы на обращение к подпрограмме, однако ведет к увеличению размера исполняемого файла. Само по себе увеличение размера исполняемого файла не является существенным, однако в некоторых случаях исполняемый код может выйти за пределы кэша команд, что повлечет значительное падение скорости исполнения программы. Поэтому современные оптимизирующие компиляторы обычно имеют настройки оптимизации по размеру кода и по скорости выполнения.
Быстродействие также зависит и от типа операндов. Например, в языке Turbo Pascal, ввиду особенностей реализации целочисленной арифметики, операция сложения оказывается наиболее медленной для операндов типа Byte и ShortInt: несмотря на то, что переменные занимают один байт, арифметические операции для них двухбайтовые и при выполнении операций над этими типами производится обнуление старшего байта регистров и операнд копируется из памяти в младший байт регистра. Это и приводит к дополнительным затратам времени.
Программируя арифметические выражения, следует выбирать такую форму их записи, чтобы количество «медленных» операций было сведено к минимуму. Рассмотрим такой пример. Пусть необходимо вычислить многочлен 4-й степени:
ax4+bx3+cx2+dx+e{\displaystyle ax^{4}+bx^{3}+cx^{2}+dx+e}При условии, что вычисление степени производится перемножением основания определенное число раз, нетрудно найти, что в этом выражении содержится 10 умножений («медленных» операций) и 4 сложения («быстрых» операций). Это же самое выражение можно записать в виде:
(((ax+b)x+c)x+d)x+e{\displaystyle (((ax+b)x+c)x+d)x+e}Такая форма записи называется схемой Горнера. В этом выражении 4 умножения и 4 сложения. Общее количество операций сократилось почти в два раза, соответственно уменьшится и время вычисления многочлена. Подобные оптимизации являются алгоритмическими и обычно не выполняются компилятором автоматически.
Циклы
Различается и время выполнения циклов разного типа. Время выполнения цикла со счетчиком и цикла с постусловием при всех прочих равных условиях , цикл с предусловием выполняется несколько дольше (примерно на 20-30 %).
При использовании вложенных циклов следует иметь в виду, что затраты процессорного времени на обработку такой конструкции могут зависеть от порядка следования вложенных циклов. Например, вложенный цикл со счетчиком на языке Turbo Pascal:
for j := 1 to 100000 do for k := 1 to 1000 do a := 1; | for j := 1 to 1000 do for k := 1 to 100000 do a := 1; |
Цикл в левой колонке выполняется примерно на 10 % дольше, чем в правой.
На первый взгляд, и в первом, и во втором случае 100 000 000 раз выполняется оператор присваивания и затраты времени на это должны быть одинаковы в обоих случаях. Но это не так. Объясняется это тем, что инициализации цикла (обработка процессором его заголовка с целью определения начального и конечного значений счётчика, а также шага приращения счётчика) требует времени. В первом случае 1 раз инициализируется внешний цикл и 100 000 раз — внутренний, то есть всего выполняется 100 001 инициализация. Во втором случае таких инициализаций оказывается всего лишь 1001.
Аналогично ведут себя вложенные циклы с предусловием и с постусловием. Можно сделать вывод, что при программировании вложенных циклов по возможности следует делать цикл с наименьшим числом повторений самым внешним, а цикл с наибольшим числом повторений — самым внутренним.
Если в циклах содержатся обращения к памяти (обычно при обработке массивов), для максимально эффективного использования кэша и механизма аппаратной предвыборки данных из памяти (англ. Hardware Prefetch) порядок обхода адресов памяти должен быть по возможности последовательным. Классическим примером подобной оптимизации является смена порядка следования вложенных циклов при выполнении умножения матриц.
При вычислении сумм часто используются циклы, содержащие одинаковые операции, относящиеся к каждому слагаемому. Это может быть, например, общий множитель (язык Turbo Pascal):
sum := 0; for i := 1 to 1000 do sum := sum + a * x[i]; | sum := 0; for i := 1 to 1000 do sum := sum + x[i]; sum := a * sum; |
Вторая форма записи цикла оказывается более экономной.
Инвариантные фрагменты кода
Оптимизация инвариантных фрагментов кода тесно связана с проблемой оптимального программирования циклов. Внутри цикла могут встречаться выражения, фрагменты которых никак не зависят от управляющей переменной цикла. Их называют инвариантными фрагментами кода. Современные компиляторы часто определяют наличие таких фрагментов и выполняют их автоматическую оптимизацию. Такое возможно не всегда, и иногда производительность программы зависит целиком от того, как запрограммирован цикл. В качестве примера рассмотрим следующий фрагмент программы (язык Turbo Pascal):
for i := 1 to n do begin ... for k := 1 to p do for m := 1 to q do begin a[k, m] := Sqrt(x * k * m - i) + Abs(u * i - x * m + k); b[k, m] := Sin(x * k * i) + Abs(u * i * m + k); end; ... am := 0; bm := 0; for k := 1 to p do for m := 1 to q do begin am := am + a[k, m] / c[k]; bm := bm + b[k, m] / c[k]; end; end;Здесь инвариантными фрагментами кода являются слагаемое Sin(x * k * i) в первом цикле по переменной m и операция деления на элемент массива c[k] во втором цикле по m. Значения синуса и элемента массива не изменяются в цикле по переменной m, следовательно, в первом случае можно вычислить значение синуса и присвоить его вспомогательной переменной, которая будет использоваться в выражении, находящемся внутри цикла. Во втором случае можно выполнить деление после завершения цикла по m. Таким образом, можно существенно сократить количество трудоёмких арифметических операций.
См. также
Литература
Ссылки
wikiredia.ru
Оптимизация кода
20 февраля 2010 г.
В процессе написания кода невозможно обнаружить все ошибки и исправить их. Написание кода, особенно в больших объёмах, дело монотонное, в чём-то нудное и часто повторяющееся, поэтому глаз замыливается. Поиск и исправление ошибок является лично для меня отдельной финишной процедурой. Кроме явных ошибок часто всплывают нелогичные участки кода, которые тоже приходится переписывать, упрощать и упразднять.
Кроме исправления ошибок и прочих недочётов необходимо озаботиться оптимизацией контента для поисковых машин. Поисковики предъявляют к сайтам определенные требования, которые с каждым годом только множатся и если вы не решили целенаправленно закрыть сайт от индексации, этих требований стоит придерживаться.
Ошибки в html-коде
Начнем с ошибок. Совершенно незачем сидеть и выискивать ошибки самому. Для этого консорциумом W3C предоставлены специальные сервисы. Код HTML можно проверить с помощью html-валидатора W3C, а каскадные таблицы стилей - с помощью css-валидатора W3C.
У меня на главной странице две ошибки (было на момент написания статьи ) - обе из-за тега кнопки google+, которого нет в спецификации.
<g:plusone href="http://nevor.ru">Убираем эти несоответствия и никаких претензий валидатор к моему коду не имеет:
Но google+ штука куда более нужная, чем картинка от W3C, поэтому я оставлю эти ошибки там, где они и были. Это не особо существенно, особенно если основной код сайта валидацию проходит.
Работает валидатор W3C только со страницами, размещёнными в сети интернет. Если же вы хотите проверить локальный сайт на предмет ошибок, рекомендую пользоваться плагином HTML Validator для Firefox. Плагин встраивается в интерфейс вкладки просмотра исходного кода обозревателя (вызывается сочетанием клавиш Ctrl + U) обозревателя и базируется на том же алгоритме, что и сервис W3C. Выглядит всё это следующим образом:
Плагин не только показывает ошибки, но и дает советы по поводу того, как должно быть. Я думаю, пользователи Firefox по достоинству оценят этот замечательный инструмент разработки.
Кроссбраузерность и стандартизованный код
Есть еще одна внушительная область, именуемая кроссбраузерность. Я уже затрагивал тему кроссбраузерности в этой статье. Хоть это и нельзя назвать ошибками, различия во внешнем виде сайта в разных обозревателях заставляют не редко править исправный (такой вот каламбур) код в угоду капризам обозревателей. Самым капризным был есть и останется Internet Explorer. Есть разные хаки для Internet Explorer, которые позволяют аннулировать эти капризы. Однако, многие из этих способов воспринимаются валидатором как ошибки (по сути ими и являются).
Поэтому я не советую использовать хаки. Вместо этого можно умело пользоваться условными комментариями, о которых я также упоминал в статье, посвящённой кроссбраузерности. Пример ниже демонстрирует как с помощью условного комментария можно разместить на странице ссылку на таблицу стилей исключительно для IE. Т.к. она следует за основной таблицей, её стили будут по правилу каскадности перекрывать предыдущие (конфликтные), давая обозревателю Internet Explorer иные указания.
<link rel="stylesheet" href="style.css" type="text/css">Проблема Internet Explorer'а ещё и в том, что от версии к версии ошибки в обработке содержимого html-страниц у этого обозревателя различны. Поэтому некоторые программисты проверяют свои работы отдельно в каждой версии Explorer'а. Задача в некоторых случаях действительно необходимая. А для её выполнения можно (и нужно) пользоваться программой IETester, специально для этого созданной.
Также советую скачать портативные обозреватели с сайта Portableapps.com, распаковать их в отдельные папки, а потом установить и настроить плагин Open width (Firefox) для быстрой и простой проверки сайтов на предмет кроссбраузерности. Различные плееры, галереи и прочие навороты тоже очень желательно просмотреть во всех обозревателях перед тем как внедрять. Благо практически всегда для этого размещают демо-версии. Это что касается ошибок.
Оптимизация кода
Теперь немного об оптимизации кода. Заключается она во всяческом упрощении конструкций и решений, дабы как можно более сократить объем кода без потери качества и функционала (оптимизировать). Повторяющиеся участки (как вариант) можно объединить и представить в виде переменной php.
<?php $img="<img src='logo.jpg' alt='лого'>";?> <?php echo "$img";?>Очень часто программисты дублируют участки кода или команды вызывают десять раз
echo "<div>......"; echo "<span>......."; echo "<button type='button'>....."; echo "</button></span></div>";когда можно и нужно один:
$result ="<div>......"; $result .="<span>......."; $result .="<button type='button'>....."; $result .="</button></span></div>"; echo $result;Пример примитивный, написан для наглядности, чтобы не усложнять. Поскольку статья скорее об html-вёрстке и оформлении CSS, нежели о PHP, поскольку серверные операции с php-файлами для итоговой страницы не так важны. А вот плохо написанный HTML и CSS – очень!
Стили, часто использующиеся в коде (да и вообще все) нужно выносить в таблицу стилей. Можно часть стилей для одной какой-то страницы вынести в шапку (секция <head>). Но вообще очень желательно использовать именно таблицы стилей и не плодить их без надобности (использовать одну-две). Также код css-файла можно минимизировать с помощью онлайн-сервиса или плагина для обозревателя (Phoneix для Firefox) чтобы он быстрее загружался.
Есть еще один вид ошибок, которые не относятся к коду, но относятся к сайту - орфографические. К ним относятся собственно ошибки, а также опечатки, которые делаются по невнимательности или при наборе текста статьи с полузакрытыми глазами в три часа ночи. Так что проверяйте набранный текст на сервисе Орфограф.
Если материалы сайта оказались для вас полезными, можете поддержать дальнейшее развитие ресурса, оказав ему (и мне ) моральную и материальную поддержку.
nevor.ru
Оптимизация кода
Самая актуальная документация по Visual Studio 2017: Документация по Visual Studio 2017.
С помощью оптимизации исполняемого файла можно добиться баланса между высокой скоростью выполнения и небольшим размером кода. В данном разделе рассматриваются некоторые из доступных в Visual C++ механизмов, облегчающих оптимизацию кода.
В следующих разделах описываются некоторые из возможностей оптимизации, доступных в языке C/C++.
Директивы pragma и ключевые слова оптимизацииСписок ключевых слов и прагм, которые можно использовать в коде для повышения производительности.
Параметры компилятора, упорядоченные по категориямСписок параметров компилятора /O, которые непосредственно влияют на скорость выполнения или размер кода.
Декларатор ссылки Rvalue: &&Ссылки rvalue поддерживают реализацию семантики перемещения. Применение семантик перемещения для реализации библиотек шаблонов может значительно повысить производительность приложений, в которых эти шаблоны используются.
Pragma оптимизации
Если в каком-либо оптимизированном участке кода возникают ошибки или замедление быстродействия, для отключения оптимизации для данного участка можно использовать прагму optimize.
Следует поместить код между двумя прагмами, как показано далее.
#pragma optimize("", off) // some code here #pragma optimize("", on)Также можно отметить появление дополнительных предупреждений во время компиляции кода с оптимизацией. Это нормально, поскольку некоторые предупреждения относятся только к оптимизированному коду. Если принимать во внимание такие предупреждения, можно избежать многих проблем, связанных с оптимизацией.
Парадоксально, но оптимизация быстродействия программы может в отдельных случаях вызвать замедление быстродействия кода. Это происходит из-за того, что некоторые процессы оптимизации быстродействия увеличивают объем кода. Например, встраивание функций может свести к минимуму дополнительные издержки при вызове функций. Однако вследствие встраивания слишком большого объема кода размер программы может увеличиться настолько, что это приведет к увеличению числа ошибок страницы виртуальной памяти. Таким образом, увеличение быстродействия вследствие отказа от вызовов функции может привести к потерям в памяти подкачки.
В следующих разделах рассматриваются рекомендуемые методы программирования.
Рекомендации по оптимизации срочного кодаБолее совершенные методы написания кода могут помочь повысить производительность. В этом разделе приведены методы написания кода, которые помогают убедиться, что срочные части кода выполняются удовлетворительно.
Рекомендации по оптимизацииОбщие правила оптимизации приложения.
Вследствие того что в процессе оптимизации код, созданный компилятором, может изменяться, рекомендуется перед оптимизацией кода выполнять отладку и замерять производительность приложения.
В следующих разделах содержатся основные сведения об отладке.
В следующих разделах содержатся более подробные сведения об отладке.
В следующем наборе разделов приведена информация об оптимизации процессов построения, загрузки и выполнения кода.
Образец построения C/C++
msdn.microsoft.com
10 слов об оптимизации кода
Немного о грустном: вся наша жизнь – это борьба с тормозами. И вечно так продолжаться не может. Необходимо оптимизировать всё – начиная от своего рабочего места до времени. В этой статье я привёл примеры оптимизации кода на языке программирования Delphi, но поверь, эти советы могут пригодиться тебе и в реальной жизни, если подумать.
1. Оптимизировать можно практически всё. И даже там, где тебе кажется, что всё работает быстро, можно сделать ещё быстрее. Необходимо помнить, что любую задачу можно решить несколькими путями, и твоя задача выбрать из них наиболее рациональный.
2. Оптимизацию всегда надо начинать со слабых мест в коде программы. Обычно оптимизировать то, что и так быстро работает, необходимости не возникает. Да и эффект такой оптимизации будет минимален.
3. При оптимизации нужно разбирать все операции, каждый оператор, ничего не пропуская. Обычно оптимизацию начинают с тех мест в коде, где находятся регулярно повторяющиеся операции, циклы. То, что находится внутри цикла, будет повторена n количество раз, поэтому, чем меньше кода находится в цикле, тем быстрее процессор просчитает его. Если цикл получается слишком большой, его можно разложить на несколько более маленьких. В данном случае размер нашей программы повыситься, зато скорость увеличиться.
4. Старайтесь поменьше использовать вычисления с плавающей запятой. Любые операции с целыми числами выполняются на порядок быстрее. Операции умножения или деления также выполняются достаточно долго. Вместо умножения лучше использовать сложение, а деление можно заменить сдвигом. Сдвиг работает намного быстрее и умножения, и деления. Это связано с тем, что все числа хранятся в двоичной системе. Если перевести число из десятичной системы счисления в двоичную и сдвинуть число вправо на одну позицию, то можно заметить, что данная операция аналогична делению на 2. При сдвиге влево происходит деление числа на 2. Хоть эти операции и аналогичны, но сдвиг работает в несколько раз быстрее.
5. При создании процедур не надо обременять их большим количеством входных параметров. А всё потому, что при каждом вызове процедуры её параметры подымаются в специальную область памяти, стек, а после выхода изымаются оттуда. Также необходимо действовать аккуратно и с самими параметрами. Не надо пересылать процедурам переменные, содержащие данные большого объёма в чистом виде. Лучше передать адрес ячейки памяти, где хранятся данные, а внутри процедуры уже работать с этим адресом.
6. В самых критических моментах работы программы, например вывод на экран, можно воспользоваться языком Assembler. Даже встроенный в Delphi ассемблер намного быстрее родных функций языка. Код ассемблера можно вынести в отдельный модуль, откомпилировать и подключить к своей программе.
7. Лишних проверок не бывает. Не надо думать, что если у вас не возникла какая-то нестандартная ситуация, то она не возникнет и у пользователя. Всегда делайте проверку того, что вводит пользователь, не дожидаясь, когда эти данные понадобятся.
8. Если ты пишешь достаточно большую и громоздкую программу, добавляй в неё комментарии. Компилятор их всё равно игнорирует. И если вдруг тебе захочется продать исходные коды своих программ, комментарии повысят им цену, да и самому будет легче в них ориентироваться.
9. Для достижения хорошего эффекта ты должен знать IDE, интегрированную среду разработчика, языка, на котором ты программируешь, в нашем случае Delphi. Обычно в опциях IDE разрешается выбирать различные типы компиляторов, а по умолчанию стоит самый простой, быстро компилирующий, но создающий менее оптимизированный код. Поэтому всегда ставь самый оптимизирующий вид компилятора.
10. Старайся делать в программах стандартный интерфейс. Ну не надо делать треугольные кнопочки, нестандартные меню и прочие графические навороты. Всё это очень сильно тормозит программу, расходует большое количество ресурсов компьютера и требует дополнительного времени на разработку. К примеру, настоящий UNIX – это вообще обычный shell – строка для ввода команд.
Вот вроде и всё. Желаю, удачи в написании своих программ, просто следуй этим советам, и всё у тебя получиться.
xakep.ru
Оптимизация программного кода — это модификация программ, выполняемая оптимизирующим компилятором или интерпретатором с целью улучшения их характеристик, таких как производительности или компактности, — без изменения функциональности. Последние три слова в этом определении очень важны: как бы не улучшала оптимизация характеристики программы, она обязательно должна сохранять изначальный смысл программы при любых условиях. Именно поэтому, например, в GCC существуют различные уровни оптимизации Идём дальше: оптимизации бывают машинно-независимыми (высокоуровневыми) и машинно-зависимыми (низкоуровневыми). Смысл классификации понятен из названий, в машинно-зависимых оптимизациях используются особенности конретных архитектур, в высокоуровневых оптимизация происходит на уровне структуры кода. Оптимизации также могут классифицироваться в зависимости от области их применения на локальные (оператор, последовательность операторов, базовый блок), внутрипроцедурные, межпроцедурные, внутримодульные и глобальные (оптимизация всей программы, «оптимизация при сборке», «Link-time optimization»).
Отладка модуля с целью выявления логических ошибок Отладка ПС - это деятельность, направленная на обнаружение и исправление ошибок в ПС с использованием процессов выполнения его программ. Тестирование ПС - это процесс выполнения его программ на некотором наборе данных, для которого заранее известен результат применения или известны правила поведения этих программ. Указанный набор данных называется тестовым или просто тестом. Таким образом, отладку можно представить в виде многократного повторения трех процессов: тестирования, в результате которого может быть констатировано наличие в ПС ошибки, поиска места ошибки в программах и документации ПС и редактирования программ и документации с целью устранения обнаруженной ошибки. Другими словами: Отладка = Тестирование + Поиск ошибок + Редактирование. В зарубежной литературе отладку часто понимают только как процесс поиска и исправления ошибок (без тестирования), факт наличия которых устанавливается при тестировании. Иногда тестирование и отладку считают синонимами. В нашей стране в понятие отладки обычно включают и тестирование, поэтому мы будем следовать сложившейся традиции. Впрочем, совместное рассмотрение в данной лекции этих процессов делает указанное разночтение не столь существенным. Следует, однако, отметить, что тестирование используется и как часть процесса аттестации ПС. Принципы и виды отладки программного средства Успех отладки ПС в значительной степени предопределяет рациональная организация тестирования. При отладке ПС отыскиваются и устраняются, в основном, те ошибки, наличие которых в ПС устанавливается при тестировании. Как было уже отмечено, тестирование не может доказать правильность ПС, в лучшем случае оно может продемонстрировать наличие в нем ошибки. Другими словами, нельзя гарантировать, что тестированием ПС практически выполнимым набором тестов можно установить наличие каждой имеющейся в ПС ошибки. Поэтому возникает две задачи. Первая задача: подготовить такой набор тестов и применить к ним ПС, чтобы обнаружить в нем по возможности большее число ошибок. Однако чем дольше продолжается процесс тестирования (и отладки в целом), тем большей становится стоимость ПС. Отсюда вторая задача: определить момент окончания отладки ПС (или отдельной его компоненты). Признаком возможности окончания отладки является полнота охвата пропущенными через ПС тестами (т.е. тестами, к которым применено ПС) множества различных ситуаций, возникающих при выполнении программ ПС, и относительно редкое проявление ошибок в ПС на последнем отрезке процесса тестирования. Последнее определяется в соответствии с требуемой степенью надежности ПС, указанной в спецификации его качества. Для оптимизации набора тестов, т.е. для подготовки такого набора тестов, который позволял бы при заданном их числе (или при заданном интервале времени, отведенном на тестирование) обнаруживать большее число ошибок в ПС, необходимо, во-первых, заранее планировать этот набор и, во-вторых, использовать рациональную стратегию планирования (проектирования) тестов. Проектирование тестов можно начинать сразу же после завершения этапа внешнего описания ПС. Возможны разные подходы к выработке стратегии проектирования тестов, которые можно условно графически разместить между следующими двумя крайними подходами. Левый крайний подход заключается в том, что тесты проектируются только на основании изучения спецификаций ПС (внешнего описания, описания архитектуры и спецификации модулей). Строение модулей при этом никак не учитывается, т.е. они рассматриваются как черные ящики. Фактически такой подход требует полного перебора всех наборов входных данных, так как в противном случае некоторые участки программ ПС могут не работать при пропуске любого теста, а это значит, что содержащиеся в них ошибки не будут проявляться. Однако тестирование ПС полным множеством наборов входных данных практически неосуществимо. Правый крайний подход заключается в том, что тесты проектируются на основании изучения текстов программ с целью протестировать все пути выполнения каждой программ ПС. Если принять во внимание наличие в программах циклов с переменным числом повторений, то различных путей выполнения программ ПС может оказаться также чрезвычайно много, так что их тестирование также будет практически неосуществимо.
Модульное тестирование Каждая сложная программная система состоит из отдельных частей – модулей, выполняющих ту или иную функцию в составе системы. Для того, чтобы удостовериться в корректной работе системы в целом, необходимо вначале протестировать каждый модуль системы в отдельности. В случае возникновения проблем это позволит проще выявить модули, вызвавшие проблему, и устранить соответствующие дефекты в них. Такое тестирование модулей по отдельности получило называние модульного тестирования (unit testing). Для каждого модуля, подвергаемого тестированию, разрабатывается тестовое окружение, включающее в себя драйвер и заглушки, готовятся тест-требования и тест-планы, описывающие конкретные тестовые примеры. Основная цель модульного тестирования – удостовериться в соответствии требованиям каждого отдельного модуля системы перед тем, как будет произведена его интеграция в состав системы. При этом в ходе модульного тестирования решаются четыре основные задачи. 1. Поиск и документирование несоответствий требованиям – это классическая задача тестирования, включающая в себя не только разработку тестового окружения и тестовых примеров, но и выполнение тестов, протоколирование результатов выполнения, составление отчетов о проблемах. 2. Поддержка разработки и рефакторинга низкоуровневой архитектуры системы и межмодульного взаимодействия – эта задача больше свойственна "легким" методологиям типа XP, где применяется принцип тестирования перед разработкой (Test-driven development), при котором основным источником требований для программного модуля является тест, написанный до самого модуля. Однако, даже при классической схеме тестирования модульные тесты могут выявить проблемы в дизайне системы и нелогичные или запутанные механизмы работы с модулем. 3. Поддержка рефакторинга модулей – эта задача связана с поддержкой процесса изменения системы. Достаточно часто в ходе разработки требуется проводить рефакторинг модулей или их групп – оптимизацию или полную переделку программного кода с целью повышения его сопровождаемости, скорости работы или надежности. Модульные тесты при этом являются мощным инструментом для проверки того, что новый вариант программного кода работает в точности так же, как и старый. 4. Поддержка устранения дефектов и отладки — эта задача сопряжена с обратной связью, которую получают разработчики от тестировщиков в виде отчетов о проблемах. Подробные отчеты о проблемах, составленные на этапе модульного тестирования, позволяют локализовать и устранить многие дефекты в программной системе на ранних стадиях ее разработки или разработки ее новой функциональности. В силу того, что модули, подвергаемые тестированию, обычно невелики по размеру, модульное тестирование считается наиболее простым (хотя и достаточно трудоемким) этапом тестирования системы. Однако, несмотря на внешнюю простоту, с модульным тестированием связано две проблемы. 1. Не существует единых принципов определения того, что в точности является отдельным модулем. 2. Различия в трактовке самого понятия модульного тестирования – понимается ли под ним обособленное тестирование модуля, работа которого поддерживается только тестовым окружением, или речь идет о проверке корректности работы модуля в составе уже разработанной системы. В последнее время термин "модульное тестирование" чаще используется во втором смысле, хотя в этом случае речь скорее идет об интеграционном тестировании.
|
stydopedia.ru
Оптимизация кода страниц или в SEO мелочей нет
Фрилансер
SEO-специалистам уже давно известно, что наряду с внешними и внутренними факторами ранжирования сайтов в поисковых системах на позиции в SERP’е влияют и т.н. поведенческие (пользовательские) факторы. Несмотря на это последним уделяют недостаточное внимание. Причин этому множество. Во-первых, не все SEO-компании, особенно занимающиеся «конвейерным» клиентским продвижением, могут выделить ресурсы на анализ влияния поведенческих факторов, мониторинг показателей отказов и количество просмотров страниц, анализ трафика, идущего на сайт и т.д. Во-вторых, специалисты среднего уровня до сих пор работают по принципу «сделал Seo оптимизацию — купил ссылки — жду позиции». В третьих, некоторые оптимизаторы не уделяют внимание пользовательским факторам по той причине, что не считают это нужным, ленятся или просто не знают о них.
Тем не менее, на оптимизаторских конференциях представители Яндекса дают понять, что роль поведенческих факторов становится для поисковой системы все более значимой. Среди множества критериев, влияющих на эти факторы, является оптимизация кода страниц сайта, которой, к сожалению, очень часто не уделяют внимания при организации продвижения интернет-ресурсов.
Зачем это нужно?
Ответ прост. Оптимизация кода не только ускорит загрузку страниц, но и сделает сайт более дружелюбным к поисковым системам — код станет чистым и красивым, а его элементы будут располагаться в нужных местах. Кроме того, изначально скептически воспринятое оптимизаторами в ноябре 2009 заявление Google о том, что скорость загрузки web-документа является одним из факторов ранжирования, только подтверждает тот факт, что оптимизацией кода страниц следует заниматься. Тем более, что на этот фактор оптимизатор может влиять сам.
Составляющие оптимизации кода
Ни для кого не секрет, что поисковые роботы не видят дизайн страницы — они читают её код, причем делают это также как и человек — сверху-вниз, слева-направо. Информации, находящейся вверху кода тех или иных элементов, поисковые системы дают больший приоритет. Таким образом, при SEO-вёрстке наиболее важные элементы или контент страницы следует располагать выше второстепенных элементов. Ниже даны некоторые рекомендации для оптимизации кода страниц, которые позволят сделать кампанию по его продвижению в поисковых системах более эффективной.
1. Title, Description и Keywords — располагаем сразу после тега head>.
Данные теги должны следовать сразу после тега
. Очень часто этим пренебрегают, и нередко можно видеть, как после заголовка head идёт всё, что угодно, но только не Title и мета-теги. Многие популярные CMS, например, Joomla «грешат» этим.В приведенном выше примере, если не обращать внимание на спамный keywords, показана часть неоптимизированного поля HEAD.
2. CSS-стили и Java-скрипты — «прячем» в файлы .css и .js.
Если пренебрегать этим простым правилом, то значительную часть кода страницы могут составлять стили оформления элементов страницы и java-скрипты. Этот код является техническим, он не несёт пользователю полезной информации, т.к. в нем не сосредоточен контент, но при этом он добавляет объём для страницы. Поэтому очевидно, что для ускорения загрузки страниц и SEO-вёрстки необходимо выносить его в отдельные файлы с расширениями .css и .js.
3. Контент в коде — «выше»!
Среди вебмастеров ходит много споров на тему того, какая верстка лучше для поисковых систем — табличная или верстка слоями (div’ная). С точки зрения индексации документов отличий никаких нет, однако, табличная верстка не всегда позволяет вывести нужную часть контента вверху кода страницы в отличие от div’ной, где при грамотном с точки зрения SEO-верстки позиционировании блоков можно добиться такого эффекта, что код, содержащий нужный оптимизированный контент, будет расположен вверху. При этом визуально на странице этот блок может располагаться где угодно — как под шапкой, так и в футере сайта. Таким образом, без ущерба дизайну страницы можно добиться дружелюбности к поисковым системам.
4. Ненужный и сомнительный код — закрываем от индексации.
Элементы страниц, не несущие в себе смысловой нагрузки, нужно закрывать от индексации. Таким образом, повышается общая релевантность документа. Яндекс читает код, заключенный в парный тег , но не учитывает его при ранжировании. К ненужному и сомнительному коду можно отнести счетчики статистики (liveinternet, rambler top100, bigmir и т.п.), формы голосований и опросов, отправки заявки или поиска товара, логин-панель и т.д. Встречаются страницы, содержащие все эти элементы. Доля кода SEO-контента на таких страницах будет минимальна.
Нередко можно встретить случаи, когда на сайте используется выпадающее CSS-меню. В этих случаях, как правило, также необходимо закрыть его от индексации, поскольку оно не только будет занимать значительную часть кода, но и дублироваться на всём сайте.
5. Закомментированный код удаляем.
Просматривая исходные коды интернет-страниц, довольно часто можно увидеть закомментированные элементы. Причем иногда суммарная доля такого кода занимает более 50%. Закомментированный код может серьезно увеличить объём html-страницы, тем самым, увеличив время загрузки документа. Такой код может появляться, например, в случае, когда происходит редизайн или переверстка сайта. Верстальщик может закомментировать килобайты кода и не удалить его по окончанию работ.
6. «Скрытые» элементы. Снижение риска наложения санкций.
Если в коде страниц сайта присутствуют скрытые от поисковых систем средствами CSS-форматирования элементы, от них также необходимо избавиться. К наиболее часто встречающимся элементам этой категории относятся «display:none» и «visibility:hidden». Если проект полностью белый и Вам нечего скрывать от пользователей, не стоит рисковать и ждать возможных санкций от Яндекса.
7. Валидность & кроссбраузерность — Яндекс рекомендует.
В своих рекомендациях по созданию сайтов Яндекс отмечает, что код должен быть валидным и соответствовать стандартам W3C. Валидный код гарантированно будет совместим со всеми версиями всех браузеров и обрабатывается лучше, чем код, написанный не по спецификации. Проверить сайт на валидность кода можно на сайте http://validator.w3.org/.
На поведенческие факторы существенное влияние может оказать некроссбраузерная верстка. Сайт должен одинаково хорошо отображаться во всех современных браузерах при разных разрешениях. Довольно часто можно увидеть, когда браузер Internet Explorer некорректно отображает содержимое сайта, причем отличия с Firefox и Opera кардинальные. Если на таком сайте процент пользователей IE составит 20%, то вероятность того, что показатель отказов значительно увеличится, возрастает. Пользователь не проведет много времени на таком сайте, вероятно, сразу же закроет вкладку и никогда не вернется на сайт повторно. Верстку сайта следует поручать профессионалам, для которых понятия «валидность» и «кроссбраузерность» — не пустые звуки.
8. Оптимизация картинок под web.
Этот пункт относится больше к юзабилити, но не сказать о нем нельзя. Некоторые вебмастера не уделяют оптимизации картинок под web должного внимания. Тем не менее, каждый пользователь интернета хоть раз попадал на сайт, где текстовый контент загружался быстро, а графические изображения открывались с огромным трудом.
Выяснялось, что дело не в не самой быстрой скорости подключения к интернету, а в том, что кажущиеся мини-картинки на самом деле имеют огромные разрешения, но вместо того, чтобы сжать изображение в графическом редакторе, верстальщик в коде страницы прописал атрибутам картинок «width» и «height» значения, в 15 раз, меньшие, чем реальное разрешение фотографий. Иногда доходит до того, что в веб-документе используют изображения в формате .bmp, как известно, имеющие гораздо большие объёмы в сравнении с идентичными изображениями в форматах .jpg или .gif. В качестве примера можно привести страницу о популярном сейчас биатлоне — http://magdalena-neuner.narod.ru/nowfoto.html. Чтобы посмотреть в подгружаемом фрейме все фотографии, пользователь вынужден будет скачать порядка 20 Мб трафика, поскольку 90% изображений там выполнено в bmp-формате.
Как быть и что делать в нынешних условиях?
В большинстве случаев, на практике выходит так, что клиент заказывал создание сайта в одной веб-студии или у фрилансеров (к сожалению, данные категории не всегда имеют правильное и современное представление о SEO-верстке), а продвигать решил в одной из SEO-компаний, которые, как правило, такие проблемы не решают и продвигают то, что есть своими «конвейерными» методами. В успешной SEO-кампании в Яндексе в нынешних реалиях мелочей не бывает. Поэтому специалисты, оказывающие профессиональные услуги продвижения сайтов по высококонкурентным запросам обязательно должны иметь в своём арсенале отдел программистов и верстальщиков, а также оказывать и услуги по созданию сайтов. Заказчикам, в свою очередь, желательно ориентироваться на подрядчиков, успешно занимающихся и созданием, и продвижением сайтов одновременно или, как минимум, имеющих хорошую техническую поддержку.
Стоит отметить, что оптимизация кода страниц не гарантирует повышения позиций по ключевым запросам, но не уделять этому внимания в условиях MatrixNet и поведенческих факторов нельзя, а работать над этим нужно уже сейчас.
www.seonews.ru
Оптимизация кода Википедия
У этого термина существуют и другие значения, см. Оптимизация.Оптимизация — модификация системы для улучшения её эффективности. Система может быть одиночной компьютерной программой, цифровым устройством, набором компьютеров или даже целой сетью, такой как Интернет.
Хотя целью оптимизации является получение оптимальной системы, истинно оптимальная система в процессе оптимизации достигается далеко не всегда. Оптимизированная система обычно является оптимальной только для одной задачи или группы пользователей: где-то может быть важнее уменьшение времени, требуемого программе для выполнения работы, даже ценой потребления большего объёма памяти; в приложениях, где важнее память, могут выбираться более медленные алгоритмы с меньшими запросами к памяти.
Более того, зачастую не существует универсального решения (хорошо работающего во всех случаях), поэтому инженеры используют компромиссные (англ. tradeoff) решения для оптимизации только ключевых параметров. К тому же, усилия, требуемые для достижения полностью оптимальной программы, которую невозможно дальше улучшить, практически всегда превышают выгоду, которая может быть от этого получена, поэтому, как правило, процесс оптимизации завершается до того, как достигается полная оптимальность. К счастью, в большинстве случаев даже при этом достигаются заметные улучшения.
Оптимизация должна проводиться с осторожностью. Тони Хоар впервые произнёс, а Дональд Кнут впоследствии часто повторял известное высказывание: «Преждевременная оптимизация — это корень всех бед». Очень важно иметь для начала озвученный алгоритм и работающий прототип.
Основы[ | код]
Некоторые задачи часто могут быть выполнены более эффективно. Например, программа на языке Си, которая суммирует все целые числа от 1 до N:
int i, sum = 0; for (i = 1; i <= N; i++) sum += i;Подразумевая, что здесь нет переполнения, этот код может быть переписан в следующем виде с помощью соответствующей математической формулы:
int sum = (N * (N+1)) / 2;Понятие «оптимизация» обычно подразумевает, что система сохраняет ту же самую функциональность. Однако, значительное улучшение производительности часто может быть достигнуто и с помощью удаления избыточной функциональности. Например, если допустить, что программе не требуется поддерживать более, чем 100 элементов при вводе, то возможно использовать статическое выделение памяти вместо более медленного динамического.
Компромиссы (tradeoff)[ | код]
Оптимизация в основном фокусируется на одиночном или повторном времени выполнения, использовании памяти, дискового пространства, пропускной способности или некотором другом ресурсе. Это обычно требует компромиссов — один параметр оптимизируется за счёт других. Например, увеличение размера программного кэша чего-либо улучшает производительность времени выполнения, но также увеличивает потребление памяти. Другие распространённые компромиссы включают прозрачность кода и его выразительность, почти всегда ценой деоптимизации. Сложные специализированные алгоритмы требуют больше усилий по отладке и увеличивают вероятность ошибок.
Различные области[ | код]
В
ru-wiki.ru