#c #oop
#c #ооп
Вопрос:
Я взвешиваю различия в производительности между следующими, и у меня могут быть некоторые недостатки в моем понимании компилятора. Насколько я понимаю:
typedef struct{
void (*foo)();
} Foo;
Выделял бы достаточно места для указателя каждый раз, когда он объявляется.
Это приводит меня к разработке таких функций, как:
void foo(Foo*);
Является ли это ненужной оптимизацией?
Комментарии:
1. По некоторому определению, вся оптимизация не нужна, если нет узких мест. Но я бы лично посоветовал использовать 2-й стиль, если нет необходимости в 1-м. Даже если это не узкое место, я не вижу крошечной эмуляции фактического синтаксиса ООП, которую вы получаете в 1-м, чтобы стоило хранить что-то дополнительное, а не просто явно передавать
this
указатель, как во 2-м. Обратите внимание также, что если бы 1-му варианту требовался экземпляр, ему также нужно было бы передать его. Таким образом, он хранит ненужный указатель и все равно должен передаватьFoo*
его в любом случае. Но: это, вероятно, только мое мнение и / или зависит от более конкретного контекста, который не показан2. Спасибо, я искал второй взгляд на это.
3. Широкое обсуждение парадигм и лучших практик может быть более уместным на softwareengineering.stackexchange.com
4. Обратите внимание, что OP спрашивал не о стиле, а о производительности, что по теме.
5. Ваша кодовая база уже претерпела изменение языка программирования, не возможно ли, что сейчас ей нужен рефакторинг до более современной версии C и, возможно, несколько других вариантов дизайна, прежде чем переходить к другому языковому сдвигу?
Ответ №1:
Проблема с указателями на функции для эмуляции синтаксиса, подобного C , заключается не столько в том, что вам нужно передавать объект «this» через параметр, а в том, что вы довольно резко блокируете шансы компилятора на встраивание этих вызовов функций-членов.
Дизайн OO заключается не в использовании определенного синтаксиса, а в разработке программы. Поэтому, если вы можете использовать foo_set(amp;foo)
вместо foo.set(amp;foo)
, первое, вероятно, приведет к гораздо более эффективному коду. Особенно при вызове простых функций «установщик / получатель» из самой единицы перевода «класс».
Также, пожалуйста, обратите внимание, что void (*foo)();
это устаревший стиль в C, и вы должны писать void (*foo)(void);
вместо этого.
Комментарии:
1. Спасибо! Я полагал, что в этом случае частью проблемы была вставка — вот почему я специально ссылался на свои пробелы в знаниях в разработке компилятора. Будет ли компилятор игнорировать все указатели при встраивании или это зависит от того, сколько уровней косвенности?
2. @EvanHendler Указатели на объекты как часть списка параметров «исчезают» во время встраивания, как и любой другой параметр. Проблема здесь в том, что компиляторы обычно могут не выполнять встроенные вызовы функций через указатели на функции, что связано не с тем, какие параметры вы используете, а с характером указателей на функции во время выполнения.
3. Хорошо, это соответствовало тому, о чем я думал, без каламбура. Просто нужна фиктивная проверка.
4. В основном во время выполнения указателю присваивается адрес функции, а затем, когда вы вызываете указатель на функцию, он разыменовывает указатель и вызывает функцию.
5. Если бы он был встроен, это разрушило бы всю цель, потому что теперь указатель на функцию статичен.