Что быстрее (х <0) или (х == -1)? - PullRequest
26 голосов
/ 26 мая 2009

Переменная x - это int с возможными значениями: -1, 0, 1, 2, 3. Какое выражение будет быстрее (в тактах процессора):

1. (x < 0)
2. (x == -1)

Язык: C / C ++, но я полагаю, что все остальные языки будут такими же.

P.S. Я лично думаю, что ответ (x < 0).

Более широко для гуру: что если x с -1 до 2^30?

Ответы [ 13 ]

78 голосов
/ 26 мая 2009

Это полностью зависит от ISA, для которого вы компилируете, и качества оптимизатора вашего компилятора. Не оптимизируйте преждевременно: сначала профиль , чтобы найти узкие места .

Тем не менее, в x86 вы обнаружите, что оба одинаково быстры в большинстве случаев. В обоих случаях у вас будут инструкции сравнения (cmp) и условного перехода (jCC). Однако для (x < 0) могут быть случаи, когда компилятор может исключить инструкцию cmp, ускоряя ваш код на один полный цикл .

В частности, если значение x хранится в регистре и недавно было результатом арифметической операции (такой как add или sub, но есть еще много возможностей), которая устанавливает флаг знака SF в регистре EFLAGS нет необходимости в инструкции cmp, и компилятор может выдавать только инструкцию js. Там нет простой jCC инструкция, которая переходит, когда ввод был -1.

23 голосов
/ 26 мая 2009

Почему? Что бы вы ни делали, компилятор оптимизирует его на любой платформе, на которой вы сейчас компилируете.

Если вам нужно проверить, равен ли он -1, используйте (x == -1), если вы хотите узнать, меньше ли он нуля, используйте этот. Напиши, что бы ты прочитал вслух.

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

И даже если он не вносит никаких логических изменений, скорее всего, на вашей платформе оба будут работать за один цикл ЦП .

11 голосов
/ 26 мая 2009

Попробуйте и посмотрите! Сделайте миллион, или лучше, миллиард каждого и раз их. Могу поспорить, что в ваших результатах нет никакой статистической значимости, но кто знает - возможно, на вашей платформе и компиляторе вы можете найти результат.

Это отличный эксперимент, чтобы убедить себя, что преждевременная оптимизация, вероятно, не стоит вашего времени - и вполне может быть " корнем всего зла - по крайней мере, в программировании ".

7 голосов
/ 27 мая 2009

х <0 будет быстрее. Если ничего другого, это предотвращает выборку константы -1 в качестве операнда. Большинство архитектур имеют специальные инструкции для сравнения с нулем, так что это тоже поможет. </p>

7 голосов
/ 27 мая 2009

Это может зависеть от того, какие операции предшествуют или завершаются сравнением. Например, если вы присваиваете значение x непосредственно перед выполнением сравнения, тогда может быть быстрее проверить флаг знака, чем сравнить с конкретным значением. Или производительность предсказания ветвления процессора может зависеть от того, какое сравнение вы выберете.

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

7 голосов
/ 26 мая 2009

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

3 голосов
/ 26 мая 2009

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

Если x на самом деле и index или значение в перечислении, то -1 всегда будет тем, что вы хотите, или сработает какое-нибудь отрицательное значение? Прямо сейчас -1 - единственный минус, но это может измениться.

2 голосов
/ 26 мая 2009

Вы даже не можете ответить на этот вопрос вне контекста. Если вы попытаетесь использовать тривиальный микробенчмарк, вполне возможно, что оптимизатор внесет ваш код в эфир:

// Get time
int x = -1;
for (int i = 0; i < ONE_JILLION; i++) {
    int dummy = (x < 0); // Poof!  Dummy is ignored.
}
// Compute time difference - in the presence of good optimization
// expect this time difference to be close to useless.
1 голос
/ 25 августа 2009

Николай, вы пишите:

Это на самом деле оператор узкого места в высоконагруженная программа. Производительность в это 1-2 строки гораздо ценнее чем читаемость ...

Обычно все узкие места это маленький, даже в идеальном дизайне с совершенные алгоритмы (хотя нет например). Я делаю обработку ДНК с высокой нагрузкой и знаю мое поле и мои алгоритмы довольно хорошо

Если так, то почему бы не сделать следующее:

  1. получить таймер, установить его на 0;
  2. скомпилируйте вашу высоконагруженную программу с помощью (x <0) </strong>;
  3. запустить вашу программу и таймер;
  4. в конце программы посмотрите на таймер и запомните результат 1.
  5. такой же, как 1;
  6. скомпилируйте вашу высоконагруженную программу с помощью (x == -1) ;
  7. так же, как 3;
  8. в конце программы посмотрите на таймер и запомните результат 2.
  9. сравнить результат1 и результат2.

Вы получите ответ.

1 голос
/ 28 мая 2009

Я уверен, что вы уверены, что это реальное время.

Я бы предположил, что вопрос о машине даст более надежный ответ, чем любой из нас.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...