2014-01-17 5 views
1

Для проверки int в диапазоне [1, ∞) или нет, я могу использовать следующие способы (используйте # 1, # 2 много):Различные условные проверочные способы

  1. if (a>=1)
  2. if (a>0)
  3. if (a>1 || a==1)
  4. if (a==1 || a>1)

ли Ther что я должен обратить внимание на четыре версии?

+0

для * int *, единственные разные - 3 и 4, потому что в 3, например, 1 == будет проверяться только если a> 1 было ложным, а для 4 – user3125280

+1

оптимизация идет, первые два почти наверняка будут генерировать идентичные инструкции. Однако я не уверен в последних двух.Поскольку логический ИЛИ необходим для оценки коротких замыканий своих операндов, компилятору может потребоваться генерировать отдельные инструкции для двух тестов. Во всяком случае, это микро-оптимизация; и не делают 3 и 4, с стилистической точки зрения они выглядят странно. – Praetorian

ответ

3

Функционально нет никакой разницы между указанными вами четырьмя способами. Это в основном проблема стиля. Я бы рискнул, что №1 и №2 являются наиболее распространенными формами, хотя, если бы я видел № 3 или № 4 в обзоре кода, я бы предложил изменение.

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

0

Nope! Все они одинаковы для int. Однако я бы предпочел использовать if (a>0).

+0

оценка короткого замыкания? – user3125280

+1

Всегда есть оценка короткого замыкания в 3 и 4, но почему код выглядит плохо? –

+0

Я просто указывал, что они не одинаковые вообще, очевидно, они выглядят плохо – user3125280

1

Я действительно не понимаю, почему вы должны использовать 3 или 4. Помимо того, что они более длинны, они будут генерировать больше кода. Поскольку в состоянии or вторая проверка пропускается, если первая истинна, не должно быть производительности, за исключением версии 4, если значение не часто 1 (конечно, аппаратное обеспечение с предсказанием ветвления в основном отрицает это).

1
1. if (a>=1) 
2. if (a>0) 
3. if (a>1 || a==1) 
4. if (a==1 || a>1) 

На x86, варианты 1 и 2 производят cmp инструкцию. Это создаст различные регистры. Затем за cmp следует разветвление/скачок состояния на основе регистров. Для первого он испускает bge, для второго он испускает bgt.

Вариант 3 и 4 - в теории - требуют двух cmp s- и две ветви, но скорее всего, компилятор просто оптимизировать их быть такими же, как 1.

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

Бывают случаи, когда явно указывается «если a равно одному или имеет значение больше 1», и в те периоды времени вы должны написать if (a == 1 || a > 1). Но если вы просто проверяете, что a имеет положительное, ненулевое целочисленное значение, вы должны написать if (a > 0), так как это то, что сказано.

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

Смежные вопросы