Время компиляции и выполнения исходного кода C ++ и C - PullRequest
7 голосов
/ 24 марта 2011

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

Я надеюсь, что это не закрыто как слишком общее или расплывчатое, это просто попытка узнать фактические факты об утверждениях, которые я слышал за многие годы от многих программистов (преимущественно программистов на C).

Ответы [ 6 ]

10 голосов
/ 24 марта 2011

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

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

Существует некоторая тенденция к тому, что C ++ будет записываться несколько более широко, например, считывая данные в std::string или std::vector (или std::vector<std::string>), чтобы пользователь мог ввести произвольное количество данные без переполнения буфера или данные просто усекаются в какой-то момент. В C lot более распространено видеть, что кто-то просто кодирует буфер фиксированного размера, и если вы вводите больше, он либо переполняется, либо усекается. Очевидно, что вы платите за это - код C ++ обычно заканчивается динамическим размещением (new), которое обычно медленнее, чем просто определение массива. OTOH, если вы пишете C для достижения той же цели, вы заканчиваете тем, что пишете много дополнительного кода, и он обычно работает примерно с той же скоростью, что и версия C ++.

Другими словами, довольно легко написать C, который заметно быстрее для таких вещей, как тесты производительности и одноразовые утилиты, но преимущество в скорости испаряется в реальном коде, который должен быть надежным. В последнем случае самое лучшее, на что вы обычно можете надеяться, это то, что код C эквивалентен версии C ++, и, честно говоря, даже если делать это хорошо, довольно необычно (по крайней мере, IME).

Сравнение скорости компиляции не проще. С одной стороны, это абсолютно верно, что шаблоны могут быть медленными - по крайней мере, с большинством компиляторов, создание шаблонов довольно дорого. По принципу «строка за строкой», нет сомнений, что C почти всегда будет быстрее, чем что-либо в C ++, где много шаблонов. Проблема в том, что сравнение между строками редко имеет смысл - 10 строк C ++ могут легко быть эквивалентны сотням или даже тысячам строк C. Пока вы смотрите только на время компиляции (а не время разработки), баланс в любом случае, вероятно, благоприятствует C, но, безусловно, не почти столь же драматично, как может показаться на первый взгляд. Это также сильно зависит от компилятора: например, clang делает lot лучше, чем gcc в этом отношении (и gcc также значительно улучшился за последние несколько лет).

10 голосов
/ 24 марта 2011

Я отвечу на одну конкретную часть вопроса, которая довольно объективна. Код C ++, использующий шаблоны, будет компилироваться медленнее, чем код C. Если вы не используете шаблоны (что, вероятно, будет, если вы используете стандартную библиотеку), время компиляции должно быть очень похожим.

EDIT: С точки зрения времени выполнения это гораздо более субъективно. Несмотря на то, что C может быть языком более низкого уровня, оптимизаторы C ++ становятся действительно хорошими, и C ++ поддается более естественному представлению концепций реального мира. Если вам легче представить ваши требования в коде (как я бы сказал, в C ++), то зачастую проще написать более качественный (и более производительный) код, чем на другом языке. Я не думаю, что есть какие-либо объективные данные, показывающие, что C или C ++ быстрее во всех возможных случаях. Я бы на самом деле предложил выбрать ваш язык в зависимости от потребностей проекта, а затем написать его на этом языке. Если дела идут слишком медленно, профилируйте и используйте обычные методы повышения производительности.

6 голосов
/ 24 марта 2011

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

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

5 голосов
/ 24 марта 2011

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

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

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

http://www2.research.att.com/~bs/new_learning.pdf

Или этот отчет показывает, что многие функции C ++ не требуют затрат времени выполнения:

http://www.open -std.org / jtc1 /SC22 / wg21 / Docs / TR18015.pdf

3 голосов
/ 16 мая 2014

Хотя это старый вопрос, я бы хотел добавить сюда свои 5 центов, так как я, вероятно, не единственный, кто находит этот вопрос через поисковик.

Я не могу комментировать скорость компиляции, но скорость выполнения:

Насколько я знаю, в c ++ есть только одна функция, которая стоит производительности, даже если вы ее не используете. Эта особенность является исключением для c ++, потому что она предотвращает несколько оптимизаций компилятора (именно поэтому в c ++ 11 была введена noexcept). Однако, если вы используете какой-то механизм проверки ошибок, исключения, вероятно, будут более эффективными, чем комбинация проверки возвращаемого значения и большого количества операторов if else. Это особенно верно, если вам нужно увеличить ошибку в стеке.

В любом случае, если вы отключите исключения во время компиляции, в C ++ не будет никаких накладных расходов, за исключением случаев, когда вы намеренно используете связанные функции (например, вам не нужно платить за полиморфизм, если вы не используете виртуальные функции), тогда как большинство функций вообще не вносят накладных расходов (перегрузка, шаблоны, пространства имен aso). С другой стороны, большинство форм универсального кода будет намного быстрее в c ++, чем эквивалент в c, потому что c ++ предоставляет встроенные механизмы (шаблоны и классы) для этого. Типичным примером является csort qsort против c ++ std :: sort. Версия c ++ обычно намного быстрее, потому что внутри сортировки используемая функция компаратора известна во время компиляции, которая, по крайней мере, сохраняет вызов посредством поиска функции и в лучшем случае допускает много дополнительных оптимизаций компилятора.

Тем не менее, "проблема" в c ++ заключается в том, что легко скрыть сложность от пользователя, так что, казалось бы, невинный код может оказаться намного медленнее, чем ожидалось. Это происходит главным образом из-за перегрузки операторов, полиморфизма и конструкторов / деструкторов, но даже простой вызов функции-члена скрывает переданный this -пункт, который также не является NOP. Учитывая перегрузку операторов: когда вы видите * в c, вы знаете, что это (на большинстве архитектур) единственная дешевая инструкция на ассемблере, с другой стороны, в c ++ это может быть вызов сложной функции (подумайте о умножении матриц). Это не значит, что вы могли бы реализовать ту же функциональность в c быстрее, но в c ++ вы не видите, что это может быть дорогостоящей операцией. Деструкторы - это аналогичный случай: в «современном» c ++ вы вряд ли увидите какие-либо явные разрушения с помощью удаления, но любая локальная переменная, которая выходит из области видимости, может потенциально вызвать дорогой вызов (виртуального) деструктора без единой строки кода, указывающей на это. (игнорируя } конечно). И, наконец, некоторые люди (особенно из Java) склонны писать сложные иерархии классов с большим количеством виртуальных функций, где каждый вызов такой функции является скрытым косвенным вызовом функции, который трудно или невозможно оптимизировать. Таким образом, хотя скрывать сложность от программиста - это, в общем, хорошая вещь, иногда она оказывает негативное влияние на время выполнения, если программист не знает о стоимости этих «простых в использовании» конструкций.

В качестве резюме я бы сказал, что c ++ облегчает неопытным программистам писать медленный код (потому что они не видят неэффективности непосредственно в программе). Но c ++ также позволяет хорошим программистам писать «хороший», корректный и быстрый код быстрее, чем с c, что дает им больше времени для размышлений об оптимизации, когда они действительно необходимы.

P.S:.
Две вещи, которые я не упомянул (вероятно, среди прочих, которые я просто забыл), это способность c ++ для сложных вычислений времени компиляции (благодаря шаблонам и constexpr) и ключевое слово c restrict. Это связано с тем, что ни одна из них еще не использовалась в программах, критичных ко времени, и поэтому я не могу комментировать их общую полезность и реальный выигрыш в производительности.

0 голосов
/ 24 марта 2011

Приложения C быстрее компилируются и выполняются, чем приложения C ++.

Приложения C ++, как правило, медленнее во время выполнения и компиляции намного медленнее, чем программы на Си.

Посмотрите на эти ссылки:

...