Есть ли инструменты для отслеживания раздувания в C ++? - PullRequest
7 голосов
/ 29 июня 2010

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

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

Существуют ли какие-либо инструменты для этой работы, которые можно использовать в Windows и которые подходят для MinGW GCC или Visual Studio?

РЕДАКТИРОВАТЬ - некоторый контекст

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

Поскольку они поддерживают некоторые удобные приемы (поиск на основе пользовательских сравнений / частичных ключей, эффективный подписной доступ, поиск наименьшего неиспользованного ключа)в конечном итоге они использовались почти везде в моем коде.В настоящее время я почти никогда не использую std :: map.

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

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

У меня есть представление о том, какие методы интенсивно используются, но это хорошо известная ошибка оптимизации без профилирования.

Ответы [ 5 ]

7 голосов
/ 30 июня 2010

Проверить Сортировка символов . Я использовал это некоторое время назад, чтобы выяснить, почему наш установщик вырос в 4 раза за шесть месяцев (оказывается, что ответом было статическое связывание времени выполнения C и libxml2).

5 голосов
/ 29 июня 2010

Анализ файла карты

Я видел подобную проблему некоторое время назад, и я закончил тем, что написал собственный инструмент, который анализировал файл карты (компоновщик Visual Studio можно поручить создать).Инструмент выводил:

  • список функций, отсортированных по убыванию по размеру кода, перечисляя только первые N
  • список исходных файлов, отсортированных по убыванию по размеру кода, перечисляя только первые N

Анализ файла карты сравнительно прост (размер кода функции может быть вычислен как разница между текущей и следующей строкой), самая сложная часть - это, вероятно, разумная обработка искаженных имен.Возможно, вы найдете несколько готовых к использованию библиотек для этого, я сделал это несколько лет назад и не знаю текущей ситуации.

Вот краткий отрывок из файла карты, чтобы вы знали, чтоожидать:

Address         Publics by Value              Rva+Base       Lib:Object

0001:0023cbb4       ?ApplyScheme@Input@@QAEXPBVParamEntry@@@Z 0063dbb4 f   mainInput.obj
0001:0023cea1       ?InitKeys@Input@@QAEXXZ    0063dea1 f   mainInput.obj
0001:0023cf47       ?LoadKeys@Input@@QAEXABVParamEntry@@@Z 0063df47 f   mainInput.obj

Сортировка символов

Как указано в Ответ Бена Стауба , Сортировка символов - это готовая к использованию утилита командной строки (поставляется с полным исходным кодом C #), который делает все это, с той лишь разницей, что не анализируются файлы карт, а файлы pdb / exe.

2 голосов
/ 30 июня 2010

Итак, что я читаю, основываясь на вашем вопросе и ваших комментариях, так это то, что библиотека не на самом деле слишком велика.

Единственный инструмент, который вам нужен, чтобы определить это, это командная оболочкаили Проводник Windows.Посмотрите на размер файла.Он настолько велик, что вызывает реальные проблемы?(Недопустимое время загрузки, не помещается в памяти на целевой платформе, такого рода вещи)?

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

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

Однако, предполагая, что размер файла равен , на самом деле проблема:

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

Если вы обеспокоены тем, что встроенные функции вызывают раздувание кода, просто скомпилируйте с помощью «optimize»для размера "флаг.Затем компилятор ограничит встраивание в тех случаях, когда это не оказывает заметного влияния на размер исполняемого файла.

Чтобы выяснить, какие символы являются самыми большими, проанализируйте файл карты, как предложено @Suma.

Но на самом делеВы сказали это сами, когда упомянули «общеизвестную ошибку« оптимизация без профилирования ».

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

Профиль.Соберите данные и определите проблемные места.Прежде чем беспокоиться о том, как уменьшить размер исполняемого файла, выясните, каков размер исполняемого файла, и определите, действительно ли это является проблемой.Вы еще этого не сделали.Вы прочитали в книге, что «раздувание кода - это проблема в C ++», и поэтому вы предполагаете, что раздувание кода - это проблема в вашей программе.но так ли это?Зачем?Как вы определяете, что это?

1 голос
/ 04 февраля 2013

http://www.sikorskiy.net/prj/amap/index.html

Это замечательный объектный файл в инструменте графического интерфейса анализа размера библиотеки / библиотеки, созданный из файла карты компилятора Visual Studio.Этот инструмент анализирует и создает отчет из файла карты.Вы можете сделать фильтрацию, и он динамически отображает размер.просто введите файл карты в этот инструмент, и этот инструмент покажет, какие функции занимают, какого размера данный файл карты, сгенерированный dll / exe, проверьте скриншоты этого файла в приведенном выше файле / вы также можете отсортировать по размеру.

1 голос
/ 30 июня 2010

По сути, вы ищете дорогостоящие вещи, которые вам не нужны. Предположим, есть какая-то категория функций, которые вам не нужны, занимающие большой процент пространства, например 20%. Тогда, если вы выбрали 20 случайных байтов из размера изображения, в среднем 4 из них (20 * 20%) будут в этой категории, и вы сможете их увидеть. Итак, в основном, вы берете эти образцы, смотрите на них, и если вы видите очевидный набор функций, которые вам не нужны, то удалите их. Затем сделайте это снова , потому что другие категории подпрограмм, которые использовали меньше места, теперь занимают более высокий процент.

Так что я согласен с Suma в том, что разбор файла карты - хорошее начало. Затем я написал бы подпрограмму, чтобы пройти через нее, и каждые 5% пути (в пространстве) печатать подпрограмму, в которой я нахожусь. Таким образом, я получаю 20 образцов. Часто я нахожу, что большой кусок объектного пространства является результатом очень небольшого числа (например, 1) строк исходного кода, которые я мог бы легко сделать другим способом.

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

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

Удачи.

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