2011-04-27 2 views
13

Мне любопытно, как работает типичный профайлер C#?Как работает профайлер C#?

Есть ли специальные крючки на виртуальной машине?

Легко ли сканировать код байта для вызовов функций и вводить вызовы для запуска/остановки таймера?

Или это действительно сложно, и именно поэтому люди платят за инструменты для этого?

(как примечание стороны я нахожу немного интересным клюв это так редко - Google не попадает в лодку полностью на поиске «how does a c# profiler work?» не работает на всех - результаты о кондиционерах ...)

+3

Я жду Jon тарелочкам. –

+2

В этой статье много полезной информации: http://msdn.microsoft.com/en-us/magazine/cc301725.aspx. Также http://msdn.microsoft.com/en-us/library/bb384547.aspx –

+0

Как правило, многие профилировщики принимают очень частые снимки стека, чтобы увидеть, где он находится сейчас. Затем они создают статистику, используя эти снимки. Конечно, есть очевидная возможность, что это не так с C#, поэтому возьмите это с солью. –

ответ

3

Существует бесплатный профайлер CLR от Microsoft, версия 4.0.

https://www.microsoft.com/downloads/en/details.aspx?FamilyID=be2d842b-fdce-4600-8d32-a3cf74fda5e1

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

+3

Это полезно знать, но не имеет никакого отношения к ответу на вопрос. –

+1

+1 для борьбы с downvoter. Вы дали прямой ответ на вопрос OP. –

+0

CLR Profiler поставляется со своим источником, если кому-то интересно @, как это работает. –

1

1) Нет такой вещи, как «типичный». Люди собирают информацию о профиле различными способами: время отбирает ПК, проверяет трассировку стека, захватывает количество операций методов/операторов/скомпилированных инструкций, вставляет в код код для сбора счетчиков и, необязательно, вызывает контексты для получения данных профиля в контексте вызова основа. Каждый из этих методов может быть реализован по-разному.

2) Профилирование «C#» и профилирование «CLR». В мире MS вы можете профилировать CLR и back-translate места команд CLR на код C#. Я не знаю, использует ли Mono один и тот же набор команд CLR; если они этого не сделали, тогда вы не могли использовать профилировщик MS CLR; вам придется использовать профилировщик Mono IL. Или вы можете использовать исходный код C# для сбора данных профилирования, а затем компилировать/запускать/собирать эти данные на совместимом компиляторе MS, Mono или на ком-то, совместимом с C#, или на C#, работающем во встроенных системах, таких как WinCE, где пространство ценно и такие функции, как встроенные CLR, как правило, не учитываются.

Один из способов исходного кода прибора - использовать преобразования источника-источника, чтобы отобразить код из его исходного состояния в код, содержащий код сбора данных, а также исходную программу. В этом paper on instrumenting code to collect test coverage data показано, как система преобразования программ может использоваться для вставки зондов пробного охвата путем вставки операторов, которые устанавливают булевые флаги, специфичные для блока, при выполнении блока кода. Счетчик-профилировщик заменяет инструкции для инкремента для этих зондов. Профилировщик времени вставляет вычисления моментальных снимков/дельта для этих зондов. Наш C# Profiler реализует как счетное, так и временное профилирование для исходного кода C# в обоих направлениях; он также собирает данные графа вызовов с использованием более сложных зондов, которые собирают путь выполнения. Таким образом, он может генерировать временные данные на диаграммах вызовов таким образом. Эта схема работает в любом месте, где вы можете получить свои руки на половину приемлемого значения времени разрешения.

3

Легко сканировать байт-код для вызовов функций и ввести вызовы запуска/остановки таймера?

Или это действительно сложно, и именно поэтому люди платят за инструменты для этого?

Инъекционные вызовы достаточно трудны, чтобы инструменты были необходимы для этого.

Не только это сложно, это очень косвенный способ найти узкие места. Причина в том, что узким местом является одно или небольшое количество утверждений в вашем коде, которые отвечают за хороший процент времени, затрачиваемого на значительное время, что может быть значительно уменьшено - т. Е. Это действительно не необходимо, т. Е. Это расточительно. Если вы можете указать среднее время включения одной из ваших подпрограмм (включая время ввода-вывода), и ЕСЛИ вы можете умножить ее на сколько раз она была вызвана и делить на общее время, вы можете указать, в каком проценте времени рутина берет. Если процент небольшой (например, 10%), у вас, вероятно, больше проблем в другом месте. Если процент больше (например, от 20% до 99%), у вас может быть узкое место внутри процедуры. Итак, теперь у вас есть hunt внутри подпрограммы для этого, глядя на вещи, которые он называет, и сколько времени они принять. Также вы хотите избежать путаницы путем рекурсии (bugaboo графов вызовов).

Есть профайлеры (например, Zoom для Linux, Shark, & другие), которые работают по другому принципу. Принцип заключается в том, что существует стек вызовов функций, и в течение всего времени, за которое отвечает подпрограмма (либо выполняющая работу, либо ожидающая выполнения других подпрограмм, чтобы выполнить проделанную работу), это в стеке. Итак, если он отвечает за 50% времени (скажем), то это количество времени, которое он находится в стеке, независимо от того, сколько раз он был вызван, или сколько времени потребовалось за звонок. Не только процедура в стеке, но и конкретные строки кода, которые стоят времени, также находятся в стеке. Вам не нужно охотиться за ними. Другое дело, что вам не нужна точность измерения. Если вы взяли 10000 образцов стека, то виновные линии будут измеряться на уровне 50 +/- 0,5 процента. Если вы взяли 100 образцов, они будут измеряться как 50 +/- 5 процентов. Если вы взяли 10 образцов, они будут измеряться как 50 +/- 16 процентов. В каждом случае вы найдете их, и это ваша цель. (И рекурсия не имеет значения. Все это означает, что данная строка может появляться более одного раза в заданном образце образца.)

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

+0

+1! Похоже, что мы должны писать новый профайлер для dotNET с учетом этой простой концепции. Что касается UI, я думал о WinDirStat, только мы показывали время, потраченное на различные методы, сгруппированные по именам .classes. – GregC

+0

@GregC: Я писал один век назад. Я просто собирал образцы стека, когда вы нажимаете обе клавиши переключения. Затем у меня был вид бабочки, сконцентрированный на строке кода, а не на функции. Это началось с линии с высоким%, и вы могли столкнуться с соседними строками вверх и вниз. Это сделало приятную демонстрацию, но я обнаружил, что для серьезной работы она не могла побить чисто ручной метод по ряду причин, поэтому я позволил этому покоиться. Во всяком случае, если вы сделаете что-то похожее на Zoom, у вас будет победитель, IMHO. –

+0

@GregC: Я имею в виду, что, не нарушая ручной метод, уверен, что больше проблем собрать несколько образцов вручную, выбрать «горячую» линию и увидеть дерево вниз и вверх по этой линии. Это немного утомительно. Но если что-то бросается в глаза, я беру больше образцов, пока это не повторится, а затем я изучу его, чтобы рассказать, что делает программа и почему. Это может означать просмотр других данных, кроме стека. Когда я полностью пойму это, я могу сказать, действительно ли это расточительно и может быть заменено чем-то лучше. Таким образом, поиск высоких% строк - это лишь начало процесса. –

1

Это ссылка на статью, в которой обсуждаются как инструментальные и методы отбора проб:

http://smartbear.com/support/articles/aqtime/profiling/

+0

Что он говорит о выборке - это только модель gprof, почти 30 лет. Современные пробоотборники намного лучше. –

Смежные вопросы