LINUX.ORG.RU

Производительность C++

 ,


7

13

Как насчёт производительности у C++ по сравнению с C? Мои предположения на текущий момент:

1) Код, не использующий возможности C++ (то есть по сути plain C), скомпилированный C++ компилятором будет иметь абсолютно ту же производительность, что и код на С.

2) Исключения и dynamic_cast медленные. Если нам важна производительность, лучше их не использовать.

3) Класс без виртуальных методов, должен быть по производительности эквивалентен сишной структуре и функциям, обрабатывающим её. Не считая копирования. Нужно везде, где можно использовать передачу по указателю или ссылке (собственно, если в Си делать memmove при передаче структуры в качестве аргумента, то это вызовет примерно такой же оверхед, как дефолтный конструктор копирования С++. Верно?).

4) Класс с виртуальными методами полностью аналогичен пункту 3, но при вызове виртуальных методов добавляется небольшой оверхед. Сишный эквивалент obj->vtable->func(obj, ...). Если сравнивать с plain C кодом, реализующим ООП в той же манере (каждая структура-объект имеет поле, указывающее на структуру, содержащую адреса функций работы с ней), то оверхеда по сравнению с plain C не должно быть.

5) При использовании атрибута класса final (если компилятор поддерживает соответствующий стандарт) даже при наличии виртуальных методов в нём, их вызов будет превращаться в прямые вызовы функций вместо обращения к vtable, если переменная имеет соответствующий тип, а не указатель/ссылка на его предка (который не final).

6) Шаблоны могут привести к разбуханию кода. Впрочем, #define-ы и inline-функции в C++ могут устроить то же самое. Вопрос: будет ли использование шаблона с одинаковыми параметрами создавать 2 копии реализации или же всё-таки компилятор догадается сделать её лишь один раз. А если шаблон используется с одинаковыми параметрами в нескольких объектных файлах? Будет ли реализация расшариваться между ними или у каждого своя?

7) Что насчёт inline-методов класса? (те, которые описываются прямо в момент определения самого класса, внутри блока class). Может ли их реализация расшариваться между модулями или в каждом будет своя копия (допустим, метод слишком длинный, чтобы инлайнится в момент вызова)?

Я не претендую на правоту, какие-то утверждения могут быть ложными. Хотел бы узнать, как обстоят дела на самом деле. А также какие подводные камни я ещё не знаю. Разумеется, речь идёт о последних версиях gcc/clang с включённой оптимизацией не ниже -O2.

★★★★★

Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от eao197

Специально для дебилов: реализация, пусть даже inline-функций, не может рассматриваться в качестве интерфейса или деталей интерфейса.

С другой стороны, если const T& f() const объявлена встроенной, то делать её вдруг не встроенной - это значит признаться в своей недальновидности. А раз сделал встроенной, то такую функцию можно объявлять noexcept.

anonymous
()
Ответ на: комментарий от tailgunner

Я думал, обсуждается

Сейчас уже обсуждается noexcept, встроенность и контракты интерфейсов с пользователем.

anonymous
()
Ответ на: комментарий от anonymous

Мой вопрос был как раз о контракте интерфейса, ну да ладно.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

С другой стороны, если const T& f() const объявлена встроенной, то делать её вдруг не встроенной - это значит признаться в своей недальновидности.

Вы сделали мой день.

Отлейте в граните еще что-нибудь эпичное, пожалуйста.

А раз сделал встроенной, то такую функцию можно объявлять noexcept.

Пропробуйте-ка вот такую встроенную функцию объявить noexcept:

class T {
public :
  ... // all necessary constructors, copy- and move-operators.

  std::unique_ptr< T > clone() const {
    return std::make_unique<T>(*this);
  };
  ...
};

inline-овость функции не иметь ничего общего с noexcept.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Вы сделали мой день.
Отлейте в граните еще что-нибудь эпичное, пожалуйста.

Мило.

Пропробуйте-ка вот такую встроенную функцию объявить noexcept:

Причём тут эта функция, если я о (тобою же написанной)

const std::string& error_desc() const { return desc_; }
Не сможешь ты доказать, что noexcept тут использовать нельзя. А я смогу доказать, что можно, ибо это тут можно по определению.

anonymous
()
Ответ на: комментарий от anonymous

Еще раз для совсем уж дебилов: можно != нужно.

То, что можно поставить noexcept в данном конкретном случае не означает, что это нужно делать.

eao197 ★★★★★
()

Хосспаде! Такие срачи показывают не достоинства или недостатки языка, а зашкаливающее количество долбоебов в с обеих сторон.

anonymous
()
Ответ на: комментарий от anonymous

Твоя правда. Достаточно того, что плюсы — сахар для си и привносят связанные с этим фактом недостатки, в том числе в плане производительности.

Но при этом код, реализующий всякие сложные хитровыдуманные структуры смотрится лучше. Сахар же.

anonymous
()
Ответ на: комментарий от anonymous

Достаточно того, что плюсы — сахар для си и привносят связанные с этим фактом недостатки, в том числе в плане производительности.

Очевидно, что с одной из сторон долбо*бов таки больше.

eao197 ★★★★★
()

собственно, если в Си делать memmove при передаче структуры в качестве аргумента, то это вызовет примерно такой же оверхед, как дефолтный конструктор копирования С++.

нет, memmove медленнее если класс небольшой. memmove используется там где есть copy elision

ckotinko ☆☆☆
()
Ответ на: комментарий от eao197

Еще раз для совсем уж дебилов: можно != нужно.
То, что можно поставить noexcept в данном конкретном случае не означает, что это нужно делать.

Но ведь нет причин не делать этого, ибо return desc_ не может привести к исключительной ситуации.

anonymous
()
Ответ на: комментарий от anonymous

Но при этом код, реализующий всякие сложные хитровыдуманные структуры смотрится лучше. Сахар же.

Да, но сахар - не есть торт.

anonymous
()
Ответ на: комментарий от eao197

Причины должны быть для того, чтобы помечать метод/функцию атрибутом noexcept. А не наоборот.

Причина очевидна - оптимизация кода на уровне компилятора ценой набора 8 символов плюс пробел.

anonymous
()
Ответ на: комментарий от anonymous

Ну, если вы думаете, что noexcept для оптимизации, то лепите noexcept куда только сможете. Только не удивляйтесь, если вас всерьез воспринимать не будут.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Ну, если вы думаете, что noexcept для оптимизации, то лепите noexcept куда только сможете. Только не удивляйтесь, если вас всерьез воспринимать не будут.

Можно подумать здесь кто-то кого-то воспринимает всерьёз. Ты серьёзно?

anonymous
()

Хотел рассказать как устроена графическая подсистема в NT-based OS, но стало лень. Бисер перед свиньями, потому что.

lovesan ★★★
()
Ответ на: комментарий от lovesan

Хотел рассказать как устроена графическая подсистема в NT-based OS, но стало лень. Бисер перед свиньями, потому что.

это вы свинья что ли? а как она устроена знает любой виндовс разработчик

anonymous
()
Ответ на: комментарий от lovesan

ой, смотрите-ка :-) сосан самоутверждается :-) как там сисярп после лиспа? или тоже не потянул и перешел на vba?

anonymous
()
Ответ на: комментарий от anonymous

Да положить мне на жопаскрипт и нативную компиляцию, не интересно это. Ты тявкал про компиляцию жопаскрипта в webassembly, и вот конкретно за этот базар и должен отвечать. Остальное меня не колышет. Не отмазывайся теперь, сучонок, что мол это был не ты, тебя по твоим дебильным лолам узнать легко.

Хочет рассказать про компиляцию Js в WebAssembly, да передумал. Стало лень. :-)

anonymous
()
Ответ на: комментарий от anonymous

C# вообще скоро лиспом станет. Roslyn уже есть, вон, можно скрипты и репл писат прямо на C#. В 7й версии будет pattern matching(сейчас 6я в продакшне у всех, если что). Думаю к 8й там введут полноценные макросы.

lovesan ★★★
()
Ответ на: комментарий от lovesan

Думаю к 8й там введут полноценные макросы.

И что это даст человечеству?

anonymous
()

Хорошие вопросы, умные.

Запости их лучше на Stack Overflow (каждый отдельно), а сюда кинь ссылки.

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

sasha1024
()
Ответ на: комментарий от next_time

О боже, убогое днище - зачем ты мне что-то срёшь, если нулёвый балабол и всё равно обделаешься.

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

Второй случай так же не является нормальным с т.з. сравнения кода, т.к. он не является честным и не доказывать превосходство инлайна. Он лишь доказывает то, что конпелятор нихрена не может генерировать нормальный код.

Компилятор не может сводить не инлайн к инлайну и генерировать одинаковый код. Это проблема так же конмелятора, а не «не инлайна».

AnonCxx
()
Ответ на: комментарий от DarkEld3r

Правильно понимаю, что ты бы хотел в произвольных местах С++ разбавлять С?

Да, написать что-то типо:

extern "std=gnu11" {

}

Тем что void* надо явно кастить?

Тем, что в крестах нет void *, не? Сама суть указателя на воид заключается в том, что он является указателем на «любой» тип - если этой самантики нет - он не имеет смысла. То, что в крестах для него оставили нормальный каст - это проблемы крестов.

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

Отсутствие автокаста числа к указателю и наоборот.

Куча всяких фичей, аля int * ptr = (int[]){10, 20};, да всё то, что позволяет писать нормальный код на си - на крестах это постоянная борьба с днище-коепелятором.

Отсутствие сишного инлайна, тех же операций над юнионами.

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

Ну и для меня си - это нормальный, современный гнутый диалект - на с89-моче писать просто не представляется возможным в силу его убогости.

Я уж с просоня не вспомню всё то, что мне мешало писать на крестах тогда, когда я это пытался делать. Сейчас конечно в кресты начали впиливать фичи и они хотя-бы на язык становятся похожим, а не на си с классами с исключениями и убогим рантоймом из коробки.

AnonCxx
()
Ответ на: комментарий от DarkEld3r

Вся «проблема» в том, что придётся явно типы для шаблонной функции при вызове указать?

Как ты себе это представляешь для шаблонной С++ лапши? Писать портянку из сотни деклтайпов? Дектайплы для лямбды?

В конечном итоге С++ - это аллогичный кое как работающий неведомая смесь кастылей.

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

И по какой неведомой логике не работает это: [code=] template<typename ret, typename ... args> decltype(auto) call(ret f(args...), args && ... arg) { return f(std::forward<args>(arg)...); }

AnonCxx
()
Ответ на: комментарий от anonymous

Ну так поведайте миру свою версию предназначения noexcept, скоростной вы наш.

eao197 ★★★★★
()

Си плюс-плюсник чешет голову и думает: «Отчего C++ так тормозить начал».

Все переходите на Си. Кишка тонка?

anonymous
()
Ответ на: комментарий от anonymous

нормальной объектной системы

А где есть нормальная? Правда, интересно.

алгебраических типов

Во всех ООП-языках, где они есть, они через ту же жопу, что и в плюсах, - через наследование. Кто мешает?

паттерн-матчинга

Ишь чего захотел.

с указателями беда

smart pointers, boost - неужели мало?

anonymous
()
Ответ на: комментарий от RazrFalcon

Не для десктопа. Уверенно держит лидерство в своей области.

Исключительно из-за «немодности». Куча IDE на жабе написана

Академический язык.

Не совсем, он популярен в около-Xen'овой инфраструктуре

annulen ★★★★★
()
Ответ на: комментарий от DarkEld3r

Отказывайся от компьютера/телефона/интернета. Кишка тонка?

Но ведь компьютер, телефон и интернет - не являются сегодня маргинальными достижениями, в отличии от цепепе :-)

anonymous
()
Ответ на: комментарий от anonymous

smart pointers, boost - неужели мало?

Многовато.

anonymous
()
Ответ на: комментарий от annulen

Исключительно из-за «немодности». Куча IDE на жабе написана

Исключительно из-за прожорливости, не у каждого на компе 100500 памяти.

anonymous
()

Я профессионал, под разные задачи беру соответсвующие инструменты. А вы, рукожопые, можете и дальше спорить.

anonymous
()
Ответ на: комментарий от annulen

Но js нет альтернативы, а жабе есть.

anonymous
()
Ответ на: комментарий от annulen

Справедливости ради - на Java только три ide: eclipse, netbeans и idea. И все они были, изначально, написаны для самой Java, которая бесспорно популярна.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

CLion тоже, PyCharm и все остальные IDE от JetBrains, но в любом случае CLion ест памяти больше чем можно представить, особенно в дебаге, и зачастую работает медленно.

anonymous
()
Ответ на: комментарий от anonymous

CLion тоже, PyCharm и все остальные IDE от JetBrains

Было бы странно, если бы они не использовали уже имеющуюся кодовую базу.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

В любом случае, там нужна обертка для GCC и так далее, это немного другое, но все остальное по факту тоже самое.

anonymous
()
Ответ на: комментарий от RazrFalcon

Ну я сказал же, что интерфейс и так далее, ничем не отличается, они просто не могут сделать походу 1 IDE и продавать модули к ней, и вот лепят по 15 штук на каждый язык.

anonymous
()
Ответ на: комментарий от anonymous

Во всех ООП-языках, где они есть, они через ту же жопу, что и в плюсах, - через наследование. Кто мешает?

Ну вот Ocaml - вполне ООП-язык, ADT - родные.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.