Огромная разница во времени работы функции dotTrace и секундомера

Профилирование производительности нескольких функций в моем приложении C#. Я использовал.Net Секундомер для определения времени выполнения функции более 20000 звонков. И время работы составило около 2,8 мс на звонок.

Однако при использовании dotTrace в построчном режиме я обнаружил, что 20000 вызовов моей функции занимают 249 584 мс, что составляет ~12,5 мс на вызов.

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

private static Stopwatch myStop = new Stopwatch();
private MyFunction(object obj, EventArgs e)
{
    myStop.Start()

    //Code here

    myStop.Stop();
    Console.WriteLine("Time elapsed for View Update: {0}", myStop.Elapsed);
    myStop.Reset();
}

Тем не менее, мне трудно поверить, что вызов занимал в среднем 10 миллисекунд.

Есть ли что-то еще, что может повлиять на время профилировщика или секундомера? Влияет ли событие таймера отправки так сильно на время?

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

Следует отметить, что я впервые профилировал код на C# или.Net.

1 ответ

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

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

Так что ваша функция уже не такая быстрая и простая. Без профилирования ваш код может выглядеть так:

myStop.Start();
var i = 5;
i++;
myStop.Stop();

И если вы запустите его под профилировщиком, это будет так:

dotTrace.GetTime();
myStop.Start();
dotTrace.GetTime();
var i = 5;
dotTrace.GetTime();
i++;
dotTrace.GetTime();
myStop.Stop()

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

Для получения дополнительной информации о типах профилирования вы можете обратиться к разделам справки по типам профилирования dotTrace и сравнить страницы справки по типам профилирования.

Другие вопросы по тегам