Существуют ли какие-либо аспекты языка программирования C ++, когда известно, что код работает медленнее, чем эквивалентный язык C? Очевидно, что это будет исключать такие функции OO, как виртуальные функции, функции vtable и т. Д.
Я задаюсь вопросом, можете ли вы, если вы программируете в критически важной для латентной области области (и вас не волнуют функции OO), придерживаться базового C ++ или лучше C?
Ничто в стандартах языка C или C ++ не указывает скорость любой конструкции (C ++ определяет временную сложность некоторых операций, применяемых к контейнерам, но это выходит за рамки вашего вопроса). Скорость кода, сгенерированного для данной конструкции, зависит от компилятора, используемого для его компиляции, и от системы, в которой он работает.
Для данной конструкции кода, которая является допустимой C и допустимой C ++ с одинаковой семантикой, нет фундаментальный причина, почему один должен быть быстрее, чем другой. Но вполне вероятно, что один будет быстрее другого, если разработчики компилятора будут немного умнее.
Это зависит от того, что вы подразумеваете под «эквивалентом». Если вы сравните stdio.h в C с iostream в C ++, операции stdio.h, как правило, выполняются быстрее (в некоторых ситуациях немного быстрее). Но если вы говорите о коде, написанном в подмножестве C ++, который также компилируется как допустимый C, сгенерированный машинный код, вероятно, будет идентичен.
Например, в C ++ отсутствует ключевое слово restrict
, Используется правильно, что иногда позволяет компилятору генерировать более быстрый код.
restrict
, но бывает,restrict
применять и действовать соответственно, даже если ключевое слово не используется,restrict
или же __restrict
в любом случае как расширение.Но иногда (или довольно часто в некоторых областях), restrict
это действительно хорошая оптимизация, которая, как мне сказали, является одной из причин, по-прежнему использующей Fortran. Это, безусловно, одна из причин строгих правил псевдонимов в C и C ++, которые дают такую же возможность оптимизации, как restrict
для более ограниченного набора обстоятельств.
«Считаете ли вы», это зависит от того, что вы считаете «эквивалентным кодом». restrict
никогда не меняет смысла программы, которая использует ее корректно — компиляторы могут ее игнорировать. Так что не сложно описать программу, которая ее использует (для глаз компилятора C), и программу, которая не (для C ++), «эквивалентна». Версия с restrict
потребовалось больше (возможно, немного больше) усилий программиста, чтобы создать его, так как программист должен быть уверен, что он правильный, прежде чем его использовать.
Если вы имеете в виду, существует ли программа, которая является допустимой C, а также допустимой C ++, и имеет одинаковое значение в обоих, но реализации стандарта каким-то образом ограничены для ее запуска медленнее, чем реализации C, тогда я почти уверен, что ответ нет». Если вы имеете в виду, есть ли потенциальные изменения производительности, доступные в стандарте C, но не в стандарте C ++, тогда ответ «да».
Другое дело, сможете ли вы получить какую-либо выгоду от настройки, получите ли вы больше выгоды при одинаковых усилиях с другой оптимизацией, доступной на обоих языках, и достаточно ли велика какая-либо выгода для обоснования вашего выбора. язык еще один. Смехотворно легко взаимодействовать между кодом C и C ++, поэтому, если у вас есть какие-либо причины предпочитать C ++, то, как и при любой оптимизации, которая меняет ваш предпочтительный способ кодирования, переключение на C обычно будет тем, что вы сделаете, когда ваш профилировщик скажет у вас ваша функция слишком медленная, и не раньше.
Кроме того, я пытаюсь убедить себя, так или иначе, в том, что потенциальные исключения влияют на производительность, предполагая, что вы никогда не используете какой-либо тип, имеющий нетривиальный деструктор. Я подозреваю, что на практике это возможно (и это противоречит принципу «не платите за то, что вы не используете»), хотя бы потому, что в противном случае не было бы смысла в том, чтобы gcc имел -fno-exceptions
, Реализации C ++ снижают стоимость довольно низко (и это в основном в Rodata, а не в коде), но это не значит, что оно равно нулю. Код, критичный к задержке, может также быть или не быть кодом, критичным к двоичному размеру.
Опять же, это может зависеть от того, что вы подразумеваете под «эквивалентным» кодом — если мне придется скомпилировать мою так называемую «стандартную программу на C ++» с использованием нестандартного компилятора (такого как g++ -fno-exceptions
) чтобы «доказать», что код C ++ так же хорош, как и C, то в некотором смысле стандарт C ++ стоит мне чего-то.
Наконец, сама среда выполнения C ++ имеет начальную стоимость, которая не обязательно идентична стоимости запуска C для «той же» программы. Как правило, вы можете взломать, чтобы уменьшить стоимость обоих, удалив вещи, которые вам не нужны. Но это усилие, реализации не обязательно делают это для вас каждый раз, так что это не так строго Правда, в C ++ вы не платите за то, что не используете. Это общий принцип, но достижение его — это вопрос качества реализации.
Вопреки тому, что нравится думать многим программистам на C, часто можно написать более жесткий и быстрый код на C ++, не жертвуя при этом большим количеством дизайна.
Я не могу придумать ничего в C ++, которое медленнее, чем его аналог в C. Виртуальные функции НЕ исключены.
Есть ли Задержка критическая имею в виду Быстро настолько, насколько это возможно или это просто означает, что все должно бежать в предсказуемое время?
Если это второй случай, то единственное, что не работает в предсказуемое время, это new
, delete
а также try/catch
, Во встроенном программировании есть директивы, позволяющие избежать таких вызовов. В других случаях, особенно в C ++ 11, вы можете заметить, что некоторые вещи быстрее (std :: sort быстрее, чем sort ()), а некоторые немного медленнее.
Но то, что вы получаете по сравнению с C ++, это более высокие уровни абстракции, и вы не получаете ошибок в стиле C (как типичные malloc()
без соответствующего free()
)
В C ++ нет кода, чей прямой эквивалент в C более быстрый или, на самом деле, более понятный.
Если вы используете язык, который является пересечением C и C ++, то любое различие в производительности при компиляции этого кода с помощью компилятора C по сравнению с компилятором C ++ является исключительно проблемой качества реализации; нет причины, по которой один должен быть быстрее другого.
Конечно, в реальном мире, если вы используете C ++, вы программируете, используя оба дополнительные возможности что C ++ имеет над пересечением C и C ++ и используя разные идиомы чем в C. И наоборот, если вы используете C, вы, по крайней мере, используете совершенно идиомы, чем те, которые вы использовали бы в C ++, и вы также можете использовать дополнительные возможности современного языка C, которого нет в C ++, как, как упоминал Стив, restrict
ключевое слово, или VLA, или указатели на типы VLA, или составные литералы. Эти особенности мог в некоторых ситуациях дают существенные преимущества в производительности, но, по моему опыту, они не являются причиной, по которой большинство людей, предпочитающих C над C ++, делают это.
На мой взгляд, главное отличие — это идиомы. В C идиоматично создавать связанный список, помещая указатели next / prev непосредственно в структуру, которая хранится в списке, а не используя отдельный объект-оболочку для списка и узлов списка. В C идиоматично итерировать непосредственно по элементам строки как массив символов. В C идиоматично работать с объектами, которые существуют полностью в автоматическом хранилище, когда это возможно, а не выделять динамическое хранилище. И так далее. Эти идиоматический Различия — это основные способы, которыми код на С имеет тенденцию быть быстрее и легче, чем С ++.
Конечно, если вы хотите, вы можете использовать те же идиомы в C ++, поскольку большинство языковых конструкций, необходимых для большинства идиом C, существуют на пересечении C и C ++. И тогда вы также можете использовать дополнительные функции C ++, когда это необходимо. Но вы будете писать неидиоматический код C ++, и вы можете получить много критики от других программистов C ++ …