Почему отличаются (! =, <>), быстрее, чем равный (=, ==)?

Я видел сценарии просто использовать переменное присвоение, чтобы сделать задание:

$ xyz=`echo -e 'foo \n bar'`
$ echo $xyz
foo bar

Пробел автоматически объединяется и обрезается. Нужно остерегаться метасимволов оболочки (потенциальный инжекционный риск).

я также всегда рекомендовал бы дважды заключающие в кавычки подстановки переменных в условных выражениях оболочки:

if [ -n "$var" ]; then

начиная с чего-то как-o или другое содержание в переменной мог исправить Ваши тестовые аргументы.

9
задан Community 23 May 2017 в 12:04
поделиться

12 ответов

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

19
ответ дан 4 December 2019 в 06:01
поделиться

It could have something to do with branch prediction on the CPU. Static branch prediction would predict that a branch simply wouldn't be taken and fetch the next instruction. However, hardly anybody uses that anymore. Other than that, I'd say it's bull because the comparisons should be identical.

6
ответ дан 4 December 2019 в 06:01
поделиться

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

Вот некоторая разборка из оптимизации Delphi 2007. далее. (Обратите внимание, что отключение оптимизации немного изменило код, но не в значительной степени.

Unit70.pas.31: for I := 0 to 100 do
004552B5 33C0             xor eax,eax
Unit70.pas.33: if i = j then
004552B7 3B02             cmp eax,[edx]
004552B9 7506             jnz $004552c1
Unit70.pas.34: k := k+1;
004552BB FF05D0DC4500     inc dword ptr [$0045dcd0]
Unit70.pas.35: if i <> j then
004552C1 3B02             cmp eax,[edx]
004552C3 7406             jz $004552cb
Unit70.pas.36: l := l + 1;
004552C5 FF05D4DC4500     inc dword ptr [$0045dcd4]
Unit70.pas.37: end;
004552CB 40               inc eax
Unit70.pas.31: for I := 0 to 100 do
004552CC 83F865           cmp eax,$65
004552CF 75E6             jnz $004552b7
Unit70.pas.38: end;
004552D1 C3               ret 

Как видите, единственная разница между двумя случаями - это инструкция jz и инструкция jnz. Они БУДУТ работать с одинаковой скоростью. гораздо больше влияет на ситуацию то, как часто выполняется переход и помещается ли весь цикл в кеш.

6
ответ дан 4 December 2019 в 06:01
поделиться

Это также могло быть результатом неправильной интерпретации эксперимента.

Большинство компиляторов / оптимизаторов предполагают, что по умолчанию используется ветвь. Если вы инвертируете оператор и порядок if-then-else, и теперь выбранная ветвь является предложением ELSE, это может вызвать дополнительный эффект скорости в высоко вычисляемом коде (*)

(*), очевидно, вам необходимо проделать для этого много операций. Но это может иметь значение для самых жестких циклов, например, в кодеках или анализе изображений / машинном зрении, где у вас есть 50 МБ / с данных для просмотра. .... а потом я опускаюсь до этого уровня только ради действительно многоразового кода. Для обычного бизнес-кода это не стоит.

4
ответ дан 4 December 2019 в 06:01
поделиться

Well it could be or it couldn't be, that is the question :-) The thing is this is highly depending on the programming language you are using. Since all your statements will eventually end up as instructions to the CPU, the one that uses the least amount of instruction to achieve the result will be the fastest.

For example if you say bits x is equal to bits y, you could use the instruction that does an XOR using both bits as an input, if the result is anything but 0 it is not the same. So how would you know that the result is anything but 0? By using the instruction that returns true if you say input a is bigger than 0.

So this is already 2 instructions you use to do it, but since most CPU's have an instruction that does compare in a single cycle it is a bad example.

The point I am making is still the same, you can't make this generally statements without providing the programming language and the CPU architecture.

1
ответ дан 4 December 2019 в 06:01
поделиться

Просто догадываюсь, но, учитывая, что вы хотите сохранить логику, вы не можете просто заменить

if A = B then

на

if A <> B then

. Чтобы сохранить логику, исходный код должен быть чем-то вроде

if not (A = B) then

или

if A <> B then
else

, и на самом деле это может быть немного медленнее, чем тест на неравенство.

1
ответ дан 4 December 2019 в 06:01
поделиться

Этот список (при условии, что он на x86) инструкций ASM может помочь:

(Отказ от ответственности, I у меня нет ничего, кроме базового опыта написания ассемблера, так что я могу ошибиться)

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

«Мы должны забыть о малых эффективности, говорят около 97% время: преждевременная оптимизация - это root of all evil."

If you're writing one of those or similar then obviously you do care, but you didn't specify it.

1
ответ дан 4 December 2019 в 06:01
поделиться

Для языков .Net

Если вы посмотрите на IL из методов string.op_Equality и string.op_Inequality , вы увидите, что оба внутренних вызова string.Equals.

Но op_Inequality инвертирует результат. Это на два IL-оператора больше.

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

5
ответ дан 4 December 2019 в 06:01
поделиться

Хотя спонтанно; большинство других вещей в вашем коде будут влиять на производительность больше, чем выбор между == и! = (или = и <> в зависимости от языка).

Когда я провел тест на C #, более 1000000 итераций сравнения строк (содержащих алфавит , az, с двумя последними буквами, перевернутыми в одной из них), разница составляла от 0 до 1 миллисекунды.

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

Изменить: повторить тот же тест с байтовыми массивами; то же самое; разницей в производительности можно пренебречь.

4
ответ дан 4 December 2019 в 06:01
поделиться

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

2
ответ дан 4 December 2019 в 06:01
поделиться

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

1
ответ дан 4 December 2019 в 06:01
поделиться

Я сильно сомневаюсь, что есть разница в скорости. Например, для целочисленных типов вы получаете инструкцию CMP и либо JZ (переход, если ноль), либо JNZ (переход, если не ноль), в зависимости от того, использовали ли вы = или ≠. Здесь нет разницы в скорости, и я ожидаю, что это будет справедливо и для более высоких уровней.

1
ответ дан 4 December 2019 в 06:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: