2011-03-24 4 views
5

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

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

+0

Я считаю, что поиск в Google даст десять тысяч хитов по этой теме, включая многочисленные эссе и научные статьи. – Lundin

+4

@ Lundin: Я смотрю на SO как на отличный эксперт, который дает ценные советы и рекомендации, основанные на их личном и профессиональном опыте. Было бы бесполезно использовать SO, если бы вам приходилось гулять и читать десятки и тысячи эссе вместо того, чтобы извлекать выгоду из опыта других экспертов-программистов. –

+0

Проблема с этим вопросом - «та же программа в C». Проблема в том, что наивное выполнение одной и той же программы в C не дает вам той же программы. Компилятор C++ генерирует намного больше кода, который вы фактически не видите, что программист «C» должен реализовать, чтобы сделать программы одинаковыми. Таким образом, вы должны добавить третью субъективную меру к своему тесту. Сколько времени требуется, чтобы «написать» эквивалентную программу C++/C. Учитывая нетривиальное приложение, я подозреваю, что разница значительна. –

ответ

9

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

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

+0

Да, его понятно в случае шаблонов, поскольку компиляторы должны генерировать специализации. –

+0

Шаблон может также увеличить время выполнения в некотором крайнем случае из-за чрезмерной инкрустации (шаблон, как правило, поощряет встраивание, поскольку весь код должен быть доступен в заголовке) и/или из-за увеличения размера кода (когда они не встроены и компоновщик не является достаточно умный, чтобы объединить функцию, соответствующую различной конкретизации шаблона, но генерируя тот же код, подумайте 'std :: vector < int* >' и 'std :: vector < float* >'), что может привести к большему провалу кеша. –

+0

@Sylvain - Как написать это в C поможет вам с этим? –

-2

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

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

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

+4

Мне трудно поверить, что «приложения C++, как правило, медленнее во время выполнения». У вас есть доказательства этого заявления? –

+0

Некоторые из этих статей составляют 5-10 лет. Вряд ли это актуально. –

+0

@ Почему Почему? Последний C-стандарт был выпущен 12 лет назад, а последний C++-стандарт был выпущен 8 лет назад. Я вполне уверен, что с тех пор никаких революционных изменений в эффективности компилятора вообще не было. – Lundin

6

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

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

+0

При использовании только в случае необходимости исключения обычно приводят к в (очень немного) быстрее кода, чем коды возврата. –

4

Если вы скомпилируете тот же код, что и 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

+0

Проблема «Тот же код». Чтобы написать тот же код в C, который выполняется программой C++, требуется, чтобы инженер написал значительно больше исходного кода C (из-за дополнительных особенностей языка). Таким образом, тест «Тот же код» очень субъективен, когда вы просто смотрите на нетривиальную программу. –

+0

@Loki Astari: Старый комментарий, я знаю, но Бо, вероятно, имел в виду буквально тот же код - например. те же файлы, которые были скомпилированы как C++ g ++ и один раз c c gcc (конечно, это возможно только в том случае, если оно написано на пересечении c и C++). – MikeMB

+0

@MikeMB: Тогда вы пишете C. Конечно, если вы пишете C и скомпилируете его с g ++ и gcc, тогда вы получите тот же код. Но это делает вопрос не интересным, если вы посмотрите на это. –

9

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

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

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

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

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

2

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

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

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

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

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

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

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

Смежные вопросы