Подтвердить что ты не робот

Производительность попала в С++-стиле?

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

Я слышал, что некоторые броски даже бросают исключения!

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


Проводили ли какие-либо строгие тесты/профилирование для сравнения производительности прикладов стиля С++ с кастами стиля C?

Каковы были ваши результаты?

Какие выводы вы сделали?

4b9b3361

Ответ 1

Если приведение стиля С++ может быть концептуально заменено на C-стиль, то накладные расходы не будут. Если он не может, как и в случае dynamic_cast, для которого нет C-эквивалента, вы должны оплатить стоимость так или иначе.

В качестве примера приведен следующий код:

int x;
float f = 123.456;

x = (int) f;
x = static_cast<int>(f);

генерирует идентичный код для обоих приведений с VС++ - код:

00401041   fld         dword ptr [ebp-8]
00401044   call        __ftol (0040110c)
00401049   mov         dword ptr [ebp-4],eax

Единственный С++-прилив, который может бросать, dynamic_cast при бросании к ссылке. Чтобы избежать этого, нарисуйте указатель, который вернет 0, если сбой выполняется.

Ответ 2

Единственный, у кого есть дополнительные затраты во время выполнения, dynamic_cast, который имеет возможности, которые невозможно воспроизвести напрямую с помощью приведения стиля C в любом случае. Поэтому у вас нет проблем.

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

Ответ 3

Почему был бы удар производительности? Они выполняют ту же функциональность, что и C cast. Единственное отличие заключается в том, что они усваивают больше ошибок во время компиляции, и их легче искать в исходном коде.

static_cast<float>(3) в точности эквивалентен (float)3 и будет генерировать точно такой же код.

Учитывая a float f = 42.0f reinterpret_cast<int*>(&f) в точности эквивалентен (int*)&f и будет генерировать точно такой же код.

И так далее. Единственное отличие, отличное от dynamic_cast, которое, да, может вызвать исключение. Но это потому, что он делает то, что не может сделать C-стиль. Поэтому не используйте dynamic_cast, если вам не нужны его функции.

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

К сожалению. Второй пример должен быть reinterpret_cast, а не dynamic_cast, конечно. Исправлено.

Хорошо, просто для того, чтобы сделать это абсолютно ясно, вот что говорит стандарт С++:

§5.4.5:

Конверсии, выполняемые

  • a const_cast (5.2.11)
  • a static_cast (5.2.9)
  • a static_cast, за которым следует const_cast
  • a reinterpret_cast (5.2.10) или
  • a reinterpret_cast, за которым следует const_cast.

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

Итак, если что-то, так как приведение C-стиля реализовано в терминах С++-трансляций, C-стиль должен быть медленнее. (конечно, это не так, потому что компилятор генерирует один и тот же код в любом случае, но он более правдоподобен, чем приведение в стиле С++ медленнее.)

Ответ 4

Есть четыре стили стиля С++:

  • const_cast
  • static_cast
  • reinterpret_cast
  • dynamic_cast

Как уже упоминалось, первые три являются операциями во время компиляции. Для их использования не существует штрафного времени. Это сообщения компилятору о том, что данные, которые были объявлены одним способом, должны быть доступны другим способом. "Я сказал, что это был int*, но позвольте мне получить доступ к нему, как если бы это было char*, указывающее на sizeof(int) char s" или "Я сказал, что эти данные доступны только для чтения, и теперь мне нужно передать его которая не будет изменять его, но не принимает параметр в качестве ссылки на константу."

Помимо искажения данных путем кастомизации к неправильному типу и перебора данных (всегда возможность с помощью C-стиля) наиболее распространенная проблема времени выполнения с этими приведениями - это данные, которые фактически объявлены const, возможно, не могут быть закрыты неконстантно. Приведение чего-то объявленного const в неконстантное, а затем его изменение undefined. Undefined означает, что вам даже не гарантировано получить сбой.

dynamic_cast - это конструкция времени выполнения и должна иметь затраты времени выполнения.

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

Ответ 5

При использовании dynamic_cast во время выполнения выполняется несколько проверок, чтобы вы не делали что-то глупое (больше в список рассылки GCC) стоимость одного dynamic_cast зависит от того, сколько классов затронуто, какие классы затронуты и т.д.
Если вы действительно уверены, что бросок безопасен, вы все равно можете использовать reinterpret_cast.

Ответ 6

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

Я видел несколько ошибок, поданных против моего текущего компилятора, где генерация или оптимизация кода были немного разными в зависимости от того, используете ли вы стиль C-style и С++ static_cast.

Итак, если вы беспокоитесь, проверьте разборку на горячих точках. В противном случае просто избегайте динамических бросков, когда они вам не нужны. (Если вы отключите RTTI, вы не сможете использовать dynamic_cast в любом случае.)

Ответ 7

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

Если вы получаете ту же самую сборку, нет никакой разницы - ее не может быть. Единственное место, которое вам действительно нужно придерживаться со старыми кастами C, - это чистые подпрограммы и библиотеки C, где нет смысла вводить зависимость С++ только для литья типов.

Одна вещь, о которой нужно знать, это то, что броски происходят повсюду в приличном размере кода. За всю свою карьеру я никогда не искал "все броски" в логике - вы склонны искать отливки для определенного ТИПА типа "А", а поиск по "(А)" обычно так же эффективен, как и что-то вроде "static_cast <A> ". Используйте новые роли для таких вещей, как проверка типов и т.д., А не потому, что они выполняют поиск, вы никогда не сделаете этого легче.