Что быстрее (x <0) или (x ==-1)?

Если вы не знаете, сколько элементов в списке, этот подход является наиболее универсальным

>>> '[{0}]'.format(', '.join([str(i) for i in [1,2,3]]))

'[1, 2, 3]'

Он гораздо проще для списка строк

>>> '[{0}]'.format(', '.join(['a','b','c']))
'[a, b, c]'
28
задан Nikolay Vyahhi 2 June 2009 в 09:08
поделиться

13 ответов

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

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

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

а компилятор может выдать только инструкцию js . Нет простой инструкции jCC , которая перескакивает, когда входной сигнал равен -1.

а компилятор может выдать только инструкцию js . Нет простой инструкции jCC , которая перескакивает, когда входной сигнал равен -1.

78
ответ дан 28 November 2019 в 02:14
поделиться

Это зависит от архитектуры, но x == -1 более подвержен ошибкам. x <0 - правильный путь.

1
ответ дан 28 November 2019 в 02:14
поделиться

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

// 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.
2
ответ дан 28 November 2019 в 02:14
поделиться

То же самое, обе операции обычно выполняются за 1 такт.

1
ответ дан 28 November 2019 в 02:14
поделиться

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

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

7
ответ дан 28 November 2019 в 02:14
поделиться

x <0 будет быстрее. По крайней мере, он предотвращает выборку константы -1 в качестве операнда. В большинстве архитектур есть специальные инструкции для сравнения с нулем, так что это тоже поможет.

7
ответ дан 28 November 2019 в 02:14
поделиться

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

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

3
ответ дан 28 November 2019 в 02:14
поделиться

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

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

11
ответ дан 28 November 2019 в 02:14
поделиться

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

7
ответ дан 28 November 2019 в 02:14
поделиться

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

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

1
ответ дан 28 November 2019 в 02:14
поделиться

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

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

Такие крошечные вещи не сделают ничего быстрее,

23
ответ дан 28 November 2019 в 02:14
поделиться

Я уверен, что вы уверены, что это настоящий оперативник.

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

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

1
ответ дан 28 November 2019 в 02:14
поделиться

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

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

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

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

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

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

1
ответ дан 28 November 2019 в 02:14
поделиться