Подтвердить что ты не робот

Есть ли "профилировщик размера функции"?

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

Изменить: Заметьте, я использую Visual С++ в Windows.

4b9b3361

Ответ 1

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

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

Параметры:

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

Если вы хотите получить результаты для пространства имен или для каждого класса, вы можете просто grep вывод для 'namespace::', 'namespace::class_name::' и т.д.

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

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

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

Ответ 2

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

ADDED. Чтобы преобразовать декорированные имена, найденные в файле .map, в нечто более понятное для человека, вы можете использовать undname.exe, включенная в Visual Studio. Он принимает отдельные имена в командной строке, или вы можете подать файл .map.

Например,

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

Undecoration of "[email protected][email protected][email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected]@[email protected][email protected][email protected]@[email protected]@@[email protected]@@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 &)"

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

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

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

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

Ответ 5

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