В последний раз, когда я отвечал на такой вопрос, я просто написал «мера» и заполнял периодами, пока SO не принял его.
Этот ответ был понижен в голосовании 3 раза в течение нескольких минут и удален (наряду с хотя бы еще одним ответом на вопрос) модератором SO.
Тем не менее, альтернативы измерениям нет.
Так что это единственный возможный ответ.
И для того, чтобы продолжить и подробно рассказать об этом, чтобы ответ не был просто опущен и удален, вам нужно помнить, что то, что вы измеряете, - это просто: один набор измерений не обязательно расскажу что нибудь в общем, но только конкретный результат. Конечно, может показаться покровительственным упоминать такие очевидные вещи. Итак, хорошо, пусть так и будет: просто измерь.
Или, может быть, мне следует упомянуть, что у большинства процессоров есть специальная инструкция для сравнения с нулем, и, тем не менее, она не позволяет сделать вывод о производительности фрагментов кода?
Ну, я думаю, что я на этом остановлюсь. Помните: мера. И не оптимизируйте преждевременно!
РЕДАКТИРОВАТЬ :
поправка с пунктами, упомянутыми @MooingDuck в комментарии .
Вопрос:
Сравнение в C ++ с int
на x >= 0
более эффективно, чем x > -1
?
Что не так с вопросом
Дональд Кнут, автор классической трехтомной работы «Искусство компьютерного программирования», однажды написал [1],
& ldquo; Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всех зол & rdquo;
Как эффективный x >= 0
по сравнению с x > -1
чаще всего не имеет значения. То есть скорее всего, это неправильная вещь.
Как ясно это выражает то, что вы хотите сказать, гораздо важнее. Ваше время и время тех, кто поддерживает этот код, как правило, намного важнее, чем время выполнения программы. Сосредоточьтесь на том, насколько хорошо код общается с другими программистами, то есть на четкости.
Почему фокус вопроса неправильный
Ясность влияет на вероятность правильности. Любой код может быть выполнен произвольно быстро, если он не должен быть правильным. Поэтому правильность является наиболее важной и означает, что ясность очень важна & ndash; гораздо важнее, чем брить наносекунду времени выполнения & hellip;
И два выражения не эквивалентны по отношению к. ясность и WRT. к их шансу быть правильными.
Если x
является целым числом со знаком, то x >= 0
означает точно так же, как x > -1
. Но если x
является целым числом без знака, например, типа unsigned
, тогда x > -1
означает x > static_cast<unsigned>(-1)
(через неявное продвижение ), что, в свою очередь, означает x > std::numeric_limits<unsigned>::max()
. По-видимому, это не то, что программист хотел выразить!
Еще одна причина, по которой акцент делается неправильно (речь идет о микроэффективности, в то время как она должна быть ясной), заключается в том, что основное влияние на эффективность, в целом, оказывает не время отдельных операций (за исключением некоторых случаев динамического распределения) и от еще более медленных дисковых и сетевых операций), но от алгоритмическая эффективность . Например, писать & hellip;
string s = "";
for( int i = 0; i < n; ++i ) { s = s + "-"; }
довольно неэффективно, поскольку использует время, пропорциональное квадрату n , O ( n 2 ), квадратичное время .
Но вместо этого пишу &
string s = "";
for( int i = 0; i < n; ++i ) { s += "-"; }
уменьшает время до пропорционального n , O ( n ), линейное время .
Сосредоточив внимание на времени отдельных операций, можно подумать о написании '-'
вместо "-"
и таких глупых подробностей. Вместо этого, с акцентом на ясность, можно сосредоточиться на том, чтобы сделать этот код более понятным, чем с помощью цикла. Например. используя соответствующий конструктор string
:
string s( n, '-' );
Вау!
Наконец, третья причина, по которой не нужно прибегать к мелочам, заключается в том, что в целом это лишь очень малая часть кода, которая непропорционально увеличивает время выполнения.И определить эту часть (или части) нелегко, просто проанализировав код.Измерения необходимы, и этот вид измерения "где он проводит свое время" называется профилирование .
Как выяснить ответ на вопрос
Двадцать илитридцать лет назад можно было получить разумное представление об эффективности отдельных операций, просто взглянув на сгенерированный машинный код.
Например, вы можете посмотреть машинный код, запустив программу в отладчике, или выиспользуйте опцию Соответственно, чтобы попросить компилятор сгенерировать листинг на ассемблере.Примечание для g ++: опция -masm=intel
удобна для указания компилятору не генерировать ненадежную сборку синтаксиса AT & T, а вместо этого сборку синтаксиса Intel.Например, ассемблер Microsoft использует расширенный синтаксис Intel.
Сегодня процессор компьютера более интеллектуален.Он может выполнять инструкции не по порядку и даже до того, как их действие потребуется для «текущей» точки выполнения.Компилятор может предсказать это (используя эффективные знания, полученные из измерений), но у человека мало шансов.
Поэтому для обычного программиста единственным выходом является мера .
Измерять, измерять, измерять!
И в целом это включает в себя выполнение измеряемой вещи миллион раз и деление на миллион.
В противном случае время запуска ивремя взлета будет доминировать, а результатом будет мусор.
Конечно, если сгенерированный машинный код одинаков, то измерение не скажет вам ничего полезного об относительной разнице.Затем он может только указать, насколько велика ошибка измерения.Потому что тогда вы знаете, что должна быть нулевая разница.
Почему измерение является правильным подходом
Допустим, теоретические соображения в ответе SO указывают на то, что x >= -1
будет медленнее, чем x > 0
.
Компилятор может превзойти любое такое теоретическое соображение, генерируя ужасный код для этого x > 0
, возможно, из-за возможности контекстной «оптимизации», которую он затем (к сожалению!) Распознает.
Процессор компьютера также может испортить прогноз.
Так что в любом случае вам придется измерить.
Это означает, что теоретические соображения не сказали вам ничего полезного: вы будетев любом случае делать то же самое, а именно, измерять.
Почему этот подробный ответ, хотя и кажется полезным, ИМХО на самом деле не
Лично я предпочел бы одно слово «мера» в качестве ответа.
Потому что это то, к чему это сводится.
Все остальное читатель не только может фигурасам по себе, но придется в любом случае выяснить детали - так что это просто словоблудие, чтобы попытаться описать это здесь, на самом деле.
Ссылки:
[1] Кнут, Дональд. Структурированное программирование с переходом к операторам , ACM Journal Computing Surveys, том 6, № 4, декабрь 1974. с.268.