Почему моя программа работает быстрее, когда я включаю профилирование? - программирование

Почему моя программа работает быстрее, когда я включаю профилирование?

У меня есть программа, которая работает довольно медленно (занимает примерно 20 секунд даже при выпуске), поэтому, желая ее исправить, я попытался использовать Visual Studio, встроенную в профайлер. Однако, когда я запускаю программу с включенным профилированием, она заканчивается менее чем за секунду. Это затрудняет поиск узкого места. Я бы опубликовал код, но он длинный. Существуют ли очевидные или не столь очевидные причины, почему это происходит?

EDIT: Хорошо, поэтому я сузил проблему до кучи бесплатных() звонков. Когда я их прокомментирую, программа запускается в том же количестве времени, что и при профилировании. Но теперь у меня есть утечка памяти: -/

4b9b3361

Ответ 1

Причина в том, что при запуске приложения в Visual Studio к нему подключается отладчик. Когда вы запускаете его с помощью профилировщика, отладчик не подключен.

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

Если вы попытаетесь запустить .exe самостоятельно или запустили программу через IDE с помощью "Debug > Start Without Debugging" (или просто нажмите Ctrl + F5), приложение должно работать так же быстро, как и с профилировщиком.

Ответ 2

Это похоже на Heisenbug.

Они действительно случаются, и им может быть больно раскрывать.

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

Используйте разные профилировщики. Попробуйте добавить код времени вместо использования профилировщика.

Ответ 3

включение профилировщика приведет к перемещению вашего кода (немного), который, вероятно, маскирует проблему.

Самая распространенная причина hiesenbugs - это унифицированные переменные. Вторая наиболее распространенная причина - использование памяти после ее освобождения(). Поскольку ваш бесплатный, кажется, исправить это, вы можете подумать, что искать поздние ссылки, но я бы по-прежнему искал неинициализированные переменные, если бы вы были вами.

Ответ 4

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

Возможно, вы можете добавить ручные измерения времени до/после вызовов в malloc и new и распечатать время, чтобы убедиться в этом? Возможно, вы также можете проанализировать шаблоны распределения памяти, чтобы узнать, есть ли у вас проблема фрагментации кучи (возможно, просмотрев код и сделав некоторую символическую отладку в вашей голове;)

Ответ 5

Используйте неинтрузивный образец профилировщика вместо интрузивного инструментального профилировщика.

Ответ 6

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