Используйте «больше или равно» или просто «больше чем» - PullRequest
13 голосов
/ 23 октября 2008

Я помню по дням C, что нам предлагалось использовать

i > -1

вместо

i >= 0

из-за производительности.

Применимо ли это к миру C # .NET? Каковы последствия производительности использования одного над другим с современными компиляторами? т.е. достаточно ли умен компилятор, чтобы оптимизировать их для вас?

(В качестве примера попробуйте ввести вопрос "use> = or>" в поле вопроса в переполнении стека и посмотрите, что произойдет.)

Ответы [ 8 ]

46 голосов
/ 23 октября 2008

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

Я не уверен, откуда у вас предложение использовать «i> -1» вместо «i> = 0». В архитектуре x86 нет разницы, какую вы используете: в любом случае требуется ровно две инструкции ... одну для сравнения и одну для перехода:

 ;; if (i > -1) {
 cmp eax, -1
 jle else
then:
 ...
else:

 ;; if (i >= 0) {
 cmp eax, 0
 jl else
then:
 ...
else:

На большинстве известных мне RISC-архитектур "i> = 0" может на самом деле быстрее, поскольку обычно есть выделенный нулевой регистр, а "i> -1" может потребовать загрузки константы. Например, MIPS имеет только <инструкцию (нет <=). Вот как две конструкции будут (наивно!) Выражаться на языке ассемблера MIPS: </p>

 // if (i >= 0) {   (assuming i is in register %t0)

 stl $t1, $0, $t0     // in C: t1 = (0 < t0)
 beq $t1, $0, else    // jump if t1 == 0, that is if t0 >= 0
 nop
then:
 ...
else:

// if (i > -1) {    (assuming i is in register %t0)

 addi $t2, $0, -1      // in C: t2 = -1
 stl $t1, $t2, $t0      // in C: t1 = (t2 < t0) = (-1 < t0)
 bne $t1, $0, else     // jump if t1 != 0, that is if t0 > -1
 nop
then:
 ...
else:

Таким образом, в наивном общем случае фактически будет на одну команду быстрее выполнять «i> = 0» в MIPS. Конечно, код RISC настолько сильно оптимизируется, что компилятор может изменить любую из этих последовательностей команд почти до неузнаваемости: -)

Итак ... краткий ответ: нет, нет, нет разницы.

12 голосов
/ 23 октября 2008

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

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

if (length >= str.size())

против

if (length > str.size() - 1)

Я не знаю о вас, но я бы выбрал вариант 1 в любой день. :-) В случаях, которые не оказывают существенного влияния на производительность, таких как этот, более читаемый вариант должен выиграть.

9 голосов
/ 23 октября 2008

Здесь очень похожий вопрос (никакой критики не предполагается - как вы говорите, поиск символов сложен): «Следует ли использовать < или <= в цикле for»

(Да, я могу найти его легко, так как у меня много откликов на мой ответ ...)

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

5 голосов
/ 23 октября 2008

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

3 голосов
/ 23 октября 2008

Я помню из C дней, которые нам предлагали использовать .... из-за производительности.

Вы уверены в этом? Я работал с компьютерами еще в начале 70-х (да, на коленях у моего отца ...), и я никогда не видел ЦП, который не мог бы обрабатывать> = так же быстро, как>. (BH "Ветвь Высокая" против BNL "Ветвь Не Низкая" в разговоре IBM360).

2 голосов
/ 24 октября 2008

Это напоминает мне о рекомендации использовать ++ i вместо i ++ (до увеличения или после увеличения), поскольку это было предположительно на одну инструкцию быстрее. (Я забыл, где я первоначально читал об этом, но, возможно, это был журнал пользователей C / C ++ или Dr. Dobb's Journal, но я не могу найти веб-ссылку)

Я серьезно сомневаюсь, что> или> = быстрее или медленнее; вместо этого напишите свой код для ясности.

В качестве примечания я разработал предпочтение для оператора предварительного увеличения (++ i), даже если причина теперь потенциально устарела.

2 голосов
/ 24 октября 2008

Это могло бы быть правдой для некоторых теневых языков сценариев, которые разбивают> = на 2 сравнения, но кто бы ни побуждал вас использовать это для C ... ну ... вам, вероятно, следует постараться забыть все, что они когда-либо говорили вы.

0 голосов
/ 06 июня 2016

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

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

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