Сколько увеличения размера вызывают встроенные функции? - PullRequest
6 голосов
/ 07 июля 2011

Я недавно начал делать C ++ Wrapper из GTK + (ничего особенного, просто оборачивать все в классы C ++ для простоты разработки, для использования внутри компании) и для того, чтобы свести к минимуму увеличение производительности до уже медленного Gtk + я использовал встроенные функции почти везде.Взгляните на несколько функций класса ...

class Widget : public Object
{
public: // A few sample functions. gwidget is the internal GTK+ widget.
    void Show(void) { gtk_widget_show(GTK_WIDGET(gwidget)); }
    void ShowNow(void) { gtk_widget_show_now(GTK_WIDGET(gwidget)); }
    void Hide(void) { gtk_widget_hide(GTK_WIDGET(gwidget)); }
    void ShowAll(void) { gtk_widget_show_all(GTK_WIDGET(gwidget)); }
public: // the internal Gtk+ widget.
    GtkWidget* gwidget;
};

И хотя производительность практически отсутствует, а время запуска и использование памяти точно такие же, размер файла резко возросло.примерное окно C Gtk + генерирует 6,5 кб , в то время как примерное окно с использованием моей обертки генерирует 22,5 кб. , поэтому мне нужен небольшой совет.Должен ли я продолжать использовать встроенные функции?Я хочу, чтобы мои приложения были эффективными, и я могу немного пойти на компромисс с размером файла, как если бы я мог это сделать, даже если 6,5 кбайт C GTK + программа сгенерирована как 400-500 кбайт с использованием моей оболочки но НЕ БОЛЬШЕ.Я не хочу, чтобы моя оболочка производила HUGE EXES как wxWidgets или MFC.Так стоит ли использовать встроенные функции или я должен использовать нормальные?

ПРИМЕЧАНИЕ : все мои функции занимают одну или иногда две строки и не такие большие, как вы можете видеть в примере.

Ответы [ 8 ]

5 голосов
/ 07 июля 2011

Разница в размерах, скорее всего, связана с библиотеками, которые загружаются для C ++, а не в эквиваленте C, поэтому затраты библиотеки меньше.

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

Считаю, что ваше решение является хорошим способом реализации обертки.

5 голосов
/ 07 июля 2011

Я сильно подозреваю, что вы сравниваете яблоки с апельсинами.

Вы компилировали с точно таким же компилятором, с такими же флагами компиляции и создавали приложение с точной такой же функциональностью?

Если это так, разберите исполняемый файл и посмотрите, что означает дополнительный код .

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

Но, как всегда, не угадай, измерь.

У вас есть одна точка данных. Это не говорит вам много. Мы могли бы наблюдать увеличение размера файла на 350% в во всех случаях или на фиксированные 16 КБ. Вам нужно выяснить, что это такое. Так что получите еще несколько точек данных. Расширьте свою заявку. Сделайте так, чтобы оно открывало десять окон вместо одного, или иначе добавьте дополнительную функциональность. в этом случае "ваша" версия в три раза больше? Или это на 16кб больше? Или где-то посередине? Получить еще несколько точек данных, и вы сможете увидеть, как размер файла масштабируется .

Но, скорее всего, вы ни о чем не беспокоитесь по нескольким причинам:

  • компилятор C ++ рассматривает inline как подсказку. Вы облегчаете компилятору встроенную функцию, но решение остается за самим компилятором, и он пытается сделать приложение быстрым. Если размер файла начинает выходить из-под контроля, это замедлит ваш код, и поэтому ваш компилятор попытается оптимизировать его в сторону меньшего размера файла.
  • вы смотрите на пару килобайт . В возрасте терабайт жестких дисков. Если это может стать проблемой, тогда вы сможете спровоцировать эту проблему в тестовом примере. Если вы не можете написать тест, который приводит к увеличению размера файла более чем на 16 КБ, тогда не стоит беспокоиться.
  • если размер файла действительно становится проблемой, компиляторы обычно имеют флаг "оптимизировать для размера".
  • большие исполняемые файлы обычно получают свой размер, потому что они содержат много данных и ресурсов. Сам код очень редко является проблемой (если вы не помешаетесь на метапрограммировании шаблонов)
3 голосов
/ 07 июля 2011

Чтобы минимизировать производительность до и без того медленного Gtk +, я использовал встроенные функции почти везде

Компиляторы достаточно хорошо знают, когда вставлять, а когда нет встроенных функций.Ключевое слово inline на самом деле не означает, что функция будет встроенной, только то, что определения этой функции в разных единицах перевода не нарушают Правило единого определения (ODR).

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

Если вы хотите, чтобы ваш проект вырос с 6,5 кБ до 400 КБ, у вас должно быть более чем хорошо.

1 голос
/ 07 июля 2011

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

Обратите внимание, что в любом случае издержки будут незначительными.Удаление одного вызова на std::sort или создание экземпляра std::map компенсирует любое раздувание.Если вас волнует размер кода, маленькие встроенные функции - это наименьшее количество ваших забот.

1 голос
/ 07 июля 2011

Это зависит от

  • насколько велики ваши функции
  • как часто вы их используете
  • настройки компилятора (на которые вы можете влиять)
  • реализация компилятора (чего вы не можете)

и т.д.. и т. д. Другими словами, не предполагайте, измерьте . Сделайте репрезентативную часть вашего проекта с встроенными функциями и без них и посмотрите, как это повлияет на ваши конкретные обстоятельства. Любые прогнозы, которые вы получите через Интернет, будут в лучшем случае обоснованными догадками.

0 голосов
/ 07 июля 2011

Поздравляем, вы заново изобретаете GTKmm , официальные привязки C ++ для GTK +.

0 голосов
/ 07 июля 2011

Нет простого ответа.Это зависит от многих факторов:

  • сложность функции
  • архитектура процессора и модель памяти
  • реализация процедуры вызова соглашения
  • параметрМеханизм передачи, включая способ доступа к объекту this

Размер - не единственная эффективность, которую следует учитывать.На многих современных процессорах выполнение любого вида команды ветвления или вызова может остановить процессор на эквивалентное время многих команд.Часто замена инструкции call на несколько инструкций из тела функции - это большой выигрыш во времени.Это также может быть преимуществом размера кода, поскольку в регистрах ЦП уже могут быть функциональные параметры, поэтому их не нужно будет сдвигать или перемещать.

Не беспокойтесь о небольших оптимизациях, пока не возникнет известная проблема с пространством или скоростью,Затем найдите исправление 10%, которое затрагивает 90% проблемы.

0 голосов
/ 07 июля 2011

Примеры, которые вы приводите, не должны вызывать увеличения кода на вызывающей стороне.Замена встроенной функции, которая выполняет только один вызов и ничего больше, должна быть оптимизирована любым приличным компилятором.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...