Есть ли здесь «профилировщик размера функции»? - PullRequest
13 голосов
/ 27 июня 2009

После трех лет работы над проектом C ++ исполняемый файл вырос до 4 МБ. Я хотел бы увидеть, куда уходит все это пространство. Есть ли инструмент, который мог бы сообщить, какие самые большие космические свиньи? Было бы неплохо увидеть размер по классу (все функции в классе), по шаблону (все экземпляры) и по библиотеке (сколько принадлежит стандартной библиотеке C и STL? Сколько для каждой библиотеки в exe?)

Изменить: Обратите внимание, я использую Visual C ++ в Windows.

Ответы [ 5 ]

14 голосов
/ 27 июня 2009

В Linux вы можете использовать nm, чтобы показать все символы в исполняемом файле и отсортировать их в обратном порядке по размеру:

$ nm -CSr --size-sort <exe>

Параметры:

  • -C разбивает имена на C ++.
  • -S показывает размер символов.
  • --size-sort сортирует символы по размеру.
  • -r переворачивает сортировку.

Если вы хотите получить результаты по пространству имен или по классу, вы можете просто grep вывести «namespace::», «namespace::class_name::», и т. Д. .

Если вы хотите видеть только символы, которые определены в исполняемом файле (а не в другом месте, как в библиотеках), тогда добавьте --defined-only. Сортировка по размеру должна позаботиться об этом, поскольку неопределенные символы не будут иметь размер.

Для Windows вы все равно сможете использовать nm в ваших двоичных файлах, поскольку nm поддерживает COFF двоичные файлы. Вы можете установить nm через cygwin или скопировать исполняемый файл Windows в окно Linux и запустить там nm.

Вы также можете попробовать dumpbin, который выводит информацию о двоичном файле в Windows. Вы можете получить информацию о символах с помощью переключателя /SYMBOLS, но не похоже, что он непосредственно предоставляет информацию об их размере.

7 голосов
/ 27 июня 2009

В Windows при компиляции Visual Studio эта информация находится в вашем файле .map (он будет рядом с .pdb).

ДОБАВЛЕНО : Чтобы преобразовать оформленные имена, найденные в файле .map, во что-то более удобочитаемое, вы можете использовать утилиту undname.exe , входящую в состав Visual Studio. Он принимает отдельные имена в командной строке или вы можете передать его в файл .map.

Например,

Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of "?push_back@?$mini_vector@U?$Point@U?$FixedPoint@$0O@H@Math@@@Math@@$05@@QAAXABU?$Point@U?$FixedPoint@$0O@H@Math@@@Math@@@Z" is 

"public: void __cdecl mini_vector<struct Math::Point<struct Math::FixedPoint<14,int> >,6>::push_back(struct Math::Point<struct Math::FixedPoint<14,int> > const &)"
2 голосов
/ 01 апреля 2013

Я не смог заставить nm работать на меня, но сумел найти полезный инструмент под названием Sizer . Он считывает отладочную информацию, созданную Visual Studio с использованием библиотек доступа к интерфейсу отладки. Это довольно просто в использовании, как описано на сайте.

  1. Компилировать с информацией отладки в файле базы данных программы (.pdb)
  2. Запустить sizer из командной строки, например Sizer.exe <path-to-exe-file>. Выходные данные перейдут на стандартный вывод, поэтому вы, вероятно, захотите перенаправить в файл.

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

1 голос
/ 27 июня 2009

Не просто смотрите на код - ресурсы могут легко привести к росту в несколько мегабайт.

1 голос
/ 27 июня 2009

Получите карту ссылок или используйте dumpbin, чтобы получить список символов и размеров.

Скорее всего, есть много вещей, которые вам не нужны.

ДОБАВЛЕНО: Вы получили удовлетворительный ответ? Я понял, что есть два способа, которыми люди подходят к таким проблемам:

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

Лично я предпочитаю последнее - результаты быстрее.

Вы говорите, что приложение составляет 4 МБ. Предположим, что истинный необходимый размер составляет 1 МБ (или некоторый такой размер). Это означает, что если вы случайным образом выберете процедуру из файла карты, с вероятностью 75% это будет то, что вам не нужно. Узнайте, что является причиной его включения, и посмотрите, действительно ли вам это нужно.

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

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

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