C ++: Стоит ли использовать static_cast, чтобы избежать условий сравнения чисел? - PullRequest
0 голосов
/ 27 апреля 2018

Я стараюсь сделать очень эффективный код на C ++. Мне сказали, что я должен по возможности избегать условий. Поэтому я думал, что преобразование типов может сделать эту работу. Код с условием if будет выглядеть так:

double a = .512;  // some real number
double x = 1.1;  // a coordinate that gets changed when if condition is true
a *= a;  // a squared
if(a >= 1){x += .1;}

Я бы избежал условия if следующим образом.

double a = .512;  // some real number
double x = 1.1;  // a coordinate that gets changed when if condition is true
a *= a;  // a squared
x += static_cast<bool>(static_cast<int>(a)) * .1

Сначала преобразуется a в int. Это дает 0 для a<1 и ненулевое int для a>1. Затем второе преобразование преобразует все ненулевые значения int s в true. Но так ли это быстрее? Есть ли проблемы, с которыми я мог бы столкнуться, используя этот метод?

1 Ответ

0 голосов
/ 27 апреля 2018

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

  • Вы испортите и напишите код, который не является строго эквивалентным, потому что вы пропустили крайний случай или случайно вызвали неопределенное поведение.

  • Если код эквивалентен, он все равно будет скомпилирован по тем же инструкциям.

В вашем случае конверсия не эквивалентна. Согласно стандарту ( cppreference page ):

Значение типа с плавающей запятой может быть преобразовано в значение любого целого типа. Дробная часть усекается, то есть дробная часть отбрасывается. Если значение не может вписаться в тип назначения, поведение не определено (даже если тип назначения не имеет знака, арифметика по модулю не применяется). Если типом назначения является bool, это логическое преобразование (см. Ниже).

Слишком большие значения, NaN и бесконечность - все это проблемы в вашей версии.

По производительности они должны быть похожими. При использовании GCC 7.3 на godbolt ( link ) сборка не идентична, но обе они содержат один условный переход, которого вы надеялись избежать, удалив условие if.

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