Я знаю, что довольно часто слышал, что C обычно имеет преимущество в производительности по сравнению с C ++. Я не думал больше об этом, пока не понял, что MSVC, похоже, даже не поддерживает новейший стандарт C, но поддерживает новейший C99 (насколько я знаю).
Я планировал написать библиотеку с некоторым кодом для визуализации в OpenGL, чтобы я мог использовать его повторно. Я планировал написать библиотеку на C, так как любое повышение производительности приветствуется, когда дело доходит до графики.
Но стоит ли это того? Код, использующий библиотеку, вероятно, будет написан на C ++, и я предпочитаю кодировать на C ++ в целом.
Однако, если это приведет к небольшой разнице в производительности, я, скорее всего, остановлюсь на C.
Можно также отметить, что эту библиотеку я бы использовал для работы в Windows / OS X / Linux, и я, скорее всего, скомпилирую все изначально (MSVC для Windows, Clang или GCC для OS X и GCC для Linux). или, возможно, компиляторы Intel для всего).
Я посмотрел вокруг и нашел несколько тестов и тому подобное, но все, что я видел, касалось GCC, а не MSVC и Clang. Кроме того, в тестах не упоминаются стандарты используемых языков. У кого-нибудь есть мысли по этому поводу?
РЕДАКТИРОВАТЬ:Я просто хотел поделиться своей точкой зрения на этот вопрос после пары лет опыта. Я закончил тем, что написал проект, для которого я задавал этот вопрос на C ++. Примерно в то же время я начал другой проект в C, так как мы стремились добиться какой-то небольшой производительности, которую мы могли бы и хотели, чтобы проект был связываемым в C. Пару месяцев назад я достиг той точки, когда мне действительно нужны карты и расширенные возможности. манипуляции со струнами. Я знал о возможностях для этого в стандартной библиотеке C ++ и в итоге пришел к выводу, что эти структуры в стандартной библиотеке, вероятно, будут превосходить и быть более стабильными, чем карты и строки, которые я мог бы реализовать в C за разумное количество времени. Требование быть связываемым в C было легко выполнено путем написания интерфейса C для кода C ++, что было быстро выполнено с непрозрачными типами. Переписывание библиотеки в C ++, казалось, прошло намного быстрее, чем при написании ее на C, и было менее подвержено ошибкам, особенно утечкам памяти. Я также смог использовать стандартную библиотеку потоков библиотеки, которая была намного проще, чем использование реализаций для конкретной платформы. В конце концов, я считаю, что написание библиотеки на C ++ привело к большим преимуществам, возможно, с небольшими затратами на производительность. Я еще не тестировал версию C ++, но я полагаю, что даже возможно, что я достиг некоторой производительности, используя стандартные структуры данных библиотеки, чем те, которые я написал. Я полагаю, что написание библиотеки на C ++ привело к большим преимуществам с, возможно, небольшой производительностью. Я еще не тестировал версию C ++, но я полагаю, что даже возможно, что я достиг некоторой производительности, используя стандартные структуры данных библиотеки, чем те, которые я написал. Я полагаю, что написание библиотеки на C ++ привело к большим преимуществам с, возможно, небольшой производительностью. Я еще не тестировал версию C ++, но я полагаю, что даже возможно, что я достиг некоторой производительности, используя стандартные структуры данных библиотеки, чем те, которые я написал.
Ответы:
Я предполагаю, что люди часто утверждают, что C быстрее, чем C ++, потому что проще рассуждать о производительности в C. C ++ не является медленным или быстрым по своей природе, но определенный код C ++ может скрыть скрытые потери производительности. Например, могут быть копии и неявные преобразования, которые не сразу видны при просмотре некоторого фрагмента кода C ++.
Давайте возьмем следующее утверждение:
Далее предположим, что
doSomething
имеет следующую подпись:Теперь давайте попробуем проанализировать возможное влияние этого конкретного заявления на производительность.
В C последствия вполне понятны.
foo
может быть только указателем на структуру иdoSomething
должен быть указателем на функцию.*c
разыменовывает длинное иa + 5
является целочисленным сложением. Единственная неопределенность проистекает из типаa
: если это не int, будет некоторое преобразование. но кроме этого, легко измерить влияние этого единственного утверждения на производительность.Теперь давайте переключимся на C ++. Одно и то же утверждение теперь может иметь очень разные характеристики производительности:
doSomething
это может быть не виртуальная функция-член (дешево), виртуальная функция-член (немного дороже)std::function
, лямбда-выражения и т. д. Что еще хуже, этоfoo
может быть перегрузка типа классаoperator->
с некоторой операцией неизвестной сложности. Таким образом, чтобы количественно оценить стоимость звонкаdoSomething
, теперь необходимо знать точную природуfoo
иdoSomething
.a
может быть целым числом, или ссылкой на целое число (дополнительная косвенность), или типом класса, который реализуетoperator+(int)
. Оператор может даже вернуть другой тип класса, который неявно конвертируется вint
. Опять же, стоимость производительности не очевидна из одного заявления.c
может быть реализация типа классаoperator*()
. Это также может быть ссылка на иlong*
т. Д.Вы получаете картину. Из - за С ++ особенностями языка, гораздо сложнее определить затраты на производительность одной инструкции, чем это в C. Теперь в дополнении, абстракция , как
std::vector
,std::string
обычно используются в C ++, которые имеют характеристики своих собственные, и распределение шкуры динамической памяти ( также см. ответ @ Яна).Итак, суть заключается в следующем: в общем, нет никакой разницы в возможной производительности, достижимой с помощью C или C ++. Но для действительно критичного к производительности кода люди часто предпочитают использовать C, потому что есть намного меньше возможных скрытых потерь производительности.
источник
Код, написанный на C ++, может быть быстрее, чем на C, для определенных типов задач.
Если вы предпочитаете C ++, используйте C ++. Любые проблемы с производительностью будут незначительными по сравнению с алгоритмическими решениями вашего программного обеспечения.
источник
Один из принципов разработки C ++ заключается в том, что вы не платите за функции, которые не используете. Итак, если вы пишете код на C ++ и избегаете функций, которых нет в C, то полученный скомпилированный код должен быть эквивалентен по производительности (хотя вам придется это измерять).
Например, затраты на использование классов незначительны по сравнению со структурами и множеством связанных функций. Виртуальные функции будут стоить немного дороже, и вам придется измерить производительность, чтобы понять, имеет ли это значение для вашего приложения. То же самое касается любой другой функции языка C ++.
источник
this
языка указателей. Это все, что я говорил.Одна из причин того, что языки более высокого уровня иногда медленнее, заключается в том, что они могут скрывать за кулисами намного больше управления памятью, чем языки более низкого уровня.
Любой язык (или библиотека, API и т. Д.), Который абстрагируется от деталей низкого уровня, может потенциально скрывать дорогостоящие операции. Например, в некоторых языках простое удаление конечного пробела из строки приводит к выделению памяти и копированию строки. В частности, выделение памяти и копирование могут стать дорогостоящими, если они происходят многократно.
Если бы вы написали такой код на C, это было бы очевидно. В C ++, возможно, меньше, потому что выделения и копирование могут быть где-то абстрагированы в класс. Они могут даже быть скрыты за невинно выглядящим перегруженным оператором или конструктором копирования.
Так что используйте C ++, если хотите. Но не обманывайтесь кажущимся удобством абстракций, когда вы не знаете, что скрывается под ними.
Конечно, используйте профилировщик, чтобы узнать, что действительно замедляет ваш код.
источник
Что бы это ни стоило, я склонен писать свои библиотеки на C ++ 11 для расширенного набора функций. Мне нравится, когда я могу использовать в своих интересах такие вещи, как общие указатели, исключения, общее программирование и другие функции только C ++. Мне нравится C ++ 11, потому что я обнаружил, что большая его часть поддерживается на всех платформах, которые мне интересны. Visual Studio 2013 имеет множество основных языковых функций и реализаций библиотек, готовых к работе, и предположительно работает над добавлением оставшейся части. Как вы хорошо знаете, Clang и GCC поддерживают и весь набор функций.
С учетом вышесказанного я недавно прочитал о действительно великолепной стратегии развития библиотек, которая, на мой взгляд, имеет прямое отношение к вашему запросу. Статья называется «Стиль обработки ошибок переменного тока, который хорошо сочетается с исключениями C ++». Стефану Дю Туа (Stefanu Du Toit) называет эту стратегию шаблоном «песочных часов». Первый абзац статьи:
Теперь для решения вашей основной задачи: производительность.
Я хотел бы предложить, как и многие другие ответы здесь, что написание кода на любом языке будет работать так же хорошо с точки зрения производительности. С личной точки зрения, я считаю, что написание правильного кода на C ++ проще из-за особенностей языка, но я думаю, что это личное предпочтение. В любом случае, компиляторы действительно умны и склонны писать лучший код, чем вы. То есть компилятор, вероятно, оптимизирует ваш код лучше, чем вы.
Я знаю, что многие программисты говорят об этом, но первое, что вы должны сделать, это написать свой код, затем профилировать его и оптимизировать, как это делает ваш профилировщик. Ваше время будет гораздо лучше потрачено на создание функций, а затем на их оптимизацию, когда вы увидите, где находятся ваши узкие места.
Теперь для некоторых забавных чтений о том, как языковые функции и оптимизации могут действительно работать в вашу пользу:
std :: unique_ptr имеет нулевые накладные расходы
constexp позволяет вычислить во время компиляции
перемещение семантики предотвращает ненужные временные объекты
источник
std::unique_ptr has zero overhead
Это не может быть правдой (технически говоря), потому что он должен вызывать свой конструктор, если стек разматывается из-за исключения. Необработанный указатель не имеет таких издержек и все равно будет корректным, если ваш код, вероятно, не сгенерирует. Компилятор не сможет доказать это в общем случае.unique_ptr
? Он объявленnoexcept
, и поэтому, по крайней мере, он обрабатывает все исключения, но я не могу представить, какой тип исключения вообще может быть выдан.Строго говоря, разница в производительности между C ++ и C связана не с чем-то в языке, а с тем, что вас соблазняет. Это как кредитная карта против наличных. Это не заставляет вас тратить больше, но вы все равно делаете, если вы не очень дисциплинированы.
Вот пример программы, написанной на C ++, которая затем была агрессивно настроена на производительность. Вы должны знать, как выполнять агрессивную настройку производительности независимо от языка. Метод, который я использую, является случайной паузой, как показано в этом видео .
Виды дорогостоящих вещей, которые соблазняет C ++, - это чрезмерное управление памятью, программирование в стиле уведомлений, доверие счетчика программ к многоуровневым библиотекам абстракции (как сказал @Ian), скрытие медлительности и т. Д.
источник
C не имеет никакого преимущества в производительности по сравнению с C ++, если вы делаете одинаковые вещи на обоих языках. Вы можете взять любой старый код C, написанный любым приличным программистом C, и превратить его в действительный и эквивалентный код C ++, который будет работать так же быстро (если только вы и ваш компилятор не знаете, что делает ключевое слово restrict, и не используете его эффективно, но большинство людей этого не делают).
C ++ может иметь очень разную производительность, либо медленнее, либо быстрее, если (1) вы используете стандартную библиотеку C ++ для выполнения задач, которые можно сделать намного быстрее и проще без использования библиотеки, или (2) если вы используете стандартную библиотеку C ++ делать вещи намного проще и быстрее, чем переопределять библиотеку в плохом C.
источник