Хит производительности из C++ разрабатывает броски?

Кортеж является бифунктором, поэтому доступно bimap .

import Data.Bifunctor

fncnB = (* 2)
fncnA = (* 3)
fs' = map (bimap fncnA fncnB)

Сторонних библиотек не требуется.

58
задан Mysticial 29 July 2013 в 16:43
поделиться

6 ответов

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

Как пример, следующий код:

int x;
float f = 123.456;

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

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

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

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

85
ответ дан Peter Mortensen 24 November 2019 в 18:41
поделиться

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

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

41
ответ дан Daniel Earwicker 24 November 2019 в 18:41
поделиться

Существует четыре броска стиля C++:

  • const_cast
  • static_cast
  • reinterpret_cast
  • dynamic_cast

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

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

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

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

15
ответ дан Max Lybbert 24 November 2019 в 18:41
поделиться

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

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, конечно. Зафиксированный это теперь.

Хорошо, только для создания этого абсолютно ясным вот то, что говорит стандарт C++:

§5.4.5:

Преобразования, выполненные

  • a const_cast (5.2.11)
  • a static_cast (5.2.9)
  • a static_cast сопровождаемый a const_cast
  • a reinterpret_cast (5.2.10), или
  • a reinterpret_cast сопровождаемый a const_cast.

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

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

17
ответ дан Johannes Schaub - litb 24 November 2019 в 18:41
поделиться

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

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

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

3
ответ дан Peter Mortensen 24 November 2019 в 18:41
поделиться

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

4
ответ дан tstenner 24 November 2019 в 18:41
поделиться
Другие вопросы по тегам:

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