Какие вещи (или в каких случаях) могут сделать С++ медленнее C?
Это вопрос интервью, интервью было сделано.
Что может сделать С++ медленнее, чем C?
Интервьюер спросил его очень глубоко и всегда спрашивал "что-нибудь еще", когда я что-то говорил.
Мои идеи:
Функции С++, недоступные в C, могут иметь некоторую стоимость.
Например, если мы используем назначение для инициализации членов класса внутри конструктора, а не списка инициализации, конструктор по умолчанию для члена может вызываться один раз перед телом конструктора, а затем это значение уничтожается назначением.
Виртуальные функции нужно вызвать путем поиска указателя виртуальной функции. Это накладные расходы.
Любые лучшие идеи?
Любая помощь будет оценена.
спасибо!!!
Ответы
Ответ 1
Ничего. На самом деле, С++ быстрее, чем C. Когда-либо сравнивали std::sort
с qsort
?
Люди говорят, что виртуальные функции стоят времени для вызова. Они делают. Но также эквивалент C, который можно найти в vtable. Если вы пишете эквивалентную логику на обоих языках, версия С++ будет более удобной, чистой и быстрой.
Изменить: О да, вы можете вызвать printf
из С++, если хотите, или полностью переделать реализацию потока, если хотите.
И я упомянул, что производительность программы, которая вылетает из-за неправильного терминатора NULL, довольно несущественна?
Макросы и встроенные функции будут "раздувать" исполняемый файл C точно так же, как и шаблоны на С++.
Ответ 2
В С++ нет ничего по сравнению с C, но все же, идиоматический код С++ имеет тенденцию быть намного медленнее и тяжелее, чем идиоматический код C, выполняющий ту же задачу. Слово "идиоматика" здесь ключевое; если вы пишете свой C-код для выполнения задачи точно так же, как вы бы выполнили эту задачу на С++, это будет так же медленно. С другой стороны, если вы знаете, где скрытые затраты обычно ползут на С++, вы можете сделать так, чтобы они были минимальными и получили преимущества С++ без каких-либо затрат.
Прежде всего, это динамическое распределение памяти. В C вы видите каждый бит динамического распределения памяти, потому что он все явный (либо в виде вызовов на malloc
, либо вызывает функции сторонних библиотек, которые возвращают выделенные объекты). В С++ многие объекты класса, где длительность хранения объектов автоматически, по-прежнему будут иметь динамическое распределение памяти из-за скрытых распределений, происходящих в их конструкторах. Хорошая реализация С++ STL (или сторонней библиотеки) может избежать многих из этих затрат за счет включения небольших буферов внутри самих объектов и выполнения динамических распределений при необходимости большого буфера, но очень немногие делают это на практике. (Если я не ошибаюсь, llvm libС++ делает, но GCC libstdС++ этого не делает.) Поскольку это проблема качества реализации, которая часто выходит за пределы вашего собственного кода, главное, что вы можете сделать здесь, чтобы минимизировать влияние, - это осознавая, что автоматические объекты выделяют динамическую память и не создают больше, чем вам нужно (например, с помощью указателей или ссылок, когда это возможно). Это также имеет другие преимущества для вашего кода.
Другая большая область - обработка строк. В идиоматическом C строки строятся одним махом с помощью snprintf
или схожими. В С++ и многих других языках с более мощными строковыми классами/типами конкатенация (по частям) строк является идиоматической. Это очень неэффективно, что приводит к нескольким этапам выделения/удаления, копиям и т.д., Не говоря уже о результирующей фрагментации памяти. Я не уверен, какие лучшие практики для С++ будут включать (я не хорошо разбираюсь в С++), но должны быть способы минимизировать это влияние.
И вообще, конечно, скрытый код. Это своего рода уловка. В С++ легко написать код, в котором много лишнего кода, который вы никогда не видите, выполняется. Наиболее очевидными причинами являются конструкторы/деструкторы, перегруженные операторы и шаблоны. Опять же, если вы хотите сделать то же самое в C, стоимость будет такой же, но разница в том, что в C вы сразу видите стоимость, потому что вам нужно написать ее самостоятельно.
Ответ 3
Ничего себе... много любви к С++ в ответах, поэтому я буду говорить немного как Адвокат дьявола.
В масштабе атомного языка я бы согласился с тем, что мало или совсем существенно существенно "медленнее" выполняется на С++. На более высоком уровне это осложняется. С++ - полезный инструмент, но часто panache обходится ненадлежащим образом как решение для всех проблем. Это лучше, когда мы используем простейший язык для описания проблемы, а иногда и С++ в других случаях... сборку, коды операций, интерпретируемые языки.
С++ в большей степени полагается на компилятор, чтобы "интерпретировать" намерение, просматривая множество слоев шаблонов, классов, макросов и т.д.... с несколькими итерациями. Каждый цикл через перевод имеет потенциал столкнуться с законом непредвиденных последствий . Насколько мне известно, процессоры не имеют регистров или кодов операций, которые изначально обрабатывают конструкции С++, поэтому каждый из них должен быть разбит на упрощенную часть. В этой области стандарты компилятора и кода являются королями. В некоторых случаях это философский эквивалент учителя с PHD в Математике (компилятор), обучающей тремклассникам (процессору).
Мне нравится С++ и использую его консервативно, но я видел, как мало он хорошо писал на протяжении многих лет. Я хотел бы заставить некоторых взглянуть на сборку или машинный код, в конечном счете, срытого сборки, пока они не поймут, насколько это может быть свернуто. Bad C - это одно, плохой С++ может быть экспоненциально хуже.
Лучший ответ для интервью... "Когда ваша команда рассматривала С++ как не ответ на проблему?"
Ответ 4
Большинство функций на С++ - это решение для решения (потенциальной) проблемы в C (например: конструкторы для обеспечения достоверности созданных пакетов данных (struct
в C)
Это означает, что для написания правильной программы на C, которая пытается избежать проблемы, для которой есть функция С++, вам придется выполнять аналогичные действия, которые С++ делает за кулисами. Это приводит к аналогичным показателям в обоих случаях.
Конечно, вы всегда можете писать неаккуратные программы, которые "быстрее", но не будут работать корректно во всех случаях.
Ответ 5
C имеет restrict
, С++ - нет, хотя большинство компиляторов имеют его как расширение.
Там также массивы переменной длины, которые С++ не имеют.
Ответ 6
Любые лучшие идеи? Любая помощь будет оценена.
STL как таковой в С++ редко медленнее, чем специально закодированный эквивалент в C. Однако удобство STL может иногда приводить к записи медленного кода. Например, предположим, что фиксированный набор из 100 элементов, из которых сделан выбор переменной 10 или 15. Предположим, что программно-критический цикл много раз спрашивает, был ли выбран элемент i
. Быстрая структура данных для поддержки такого критического по времени цикла будет представлять собой массив (или вектор или тому подобное), равный 100 баллам. Однако для заполнения std::set<size_t>
может быть проще выполнить код на С++, чем заполнить массив. По этой причине программист на С++ может предпочесть набор по массиву.
Конечно, вопрос о том, является ли медленный код проблемой, зависит от того, насколько много будет работать критический по времени цикл. Если для программирования метода массива требуется дополнительные полчаса, а общая экономия времени выполнения в течение всего срока службы программы составляет 0,5 секунды, то, вероятно, предпочтительнее использовать установленную технику. С другой стороны, если общая экономия времени выполнения составляет 30 дней, то метод массива может быть предпочтительным.
Можно дать много похожих ответов на эти строки. Удачи вам в интервью.
Ответ 7
Априорно не проблема производительности, но в кодовой базе LLVM не используются ни RTTI, ни исключения, поскольку они считаются слишком дорогостоящими с точки зрения размера кода.