Измерение производительности ASP.NET MVC 3
Я создал службу JSON в ASP.NET MVC 3, и я хочу иметь возможность измерять время выполнения действий в моем приложении (я хочу, чтобы он автоматически записывал медленные действия).
Для этого это выглядело великолепно; http://coderjournal.com/2010/10/timing-the-execution-time-of-your-mvc-actions/ (здесь также упоминалось о переполнении стека)
Проблема заключается в том, что я получаю измерения, которые ДОЛЖНЫ быть ошибочными из этого метода;
Я добавил еще один секундомер, который запускает первую вещь в действии и останавливается перед возвратом.
Пример:
- Секундомер внутри метода = > 10 мс (сериализация для json здесь опущена, поэтому я могу понять, что она короче, чем реальность)
- Атрибут секундомера (код выше) = > 676 мс
- Firefox говорит, что запрос занял = > 70 мс.
Я считаю, что firefox имеет правильное время здесь (но он включает загрузку, поэтому он немного большой), но я хочу понять, почему код атрибута не работает, какие-либо идеи для этого?
Ответы
Ответ 1
Это не может быть причиной того, что это показывает длительное время выполнения, но этот атрибут будет работать неправильно с mvc 3, если у вас сразу несколько запросов.
В предыдущих версиях ASP.NET MVC, фильтры действий создаются за запрос за исключением нескольких случаев. Это поведение никогда не было гарантированным поведением, но просто деталь реализации и контракт на фильтры должен был рассмотрите их без гражданства. В ASP.NET MVC 3, фильтры кэшируются больше агрессивно. Поэтому любой пользовательский фильтры действия, которые неправильно хранятся состояние экземпляра может быть нарушено.
Я бы рекомендовал создать новый секундомер в OnActionExecuting
и сохранить его в HttpContext.Current.Items
- тогда вы можете получить его в OnActionExecuted
и распечатать результат.
Ответ 2
Более правильный подход в дополнение к ответу fooobar.com/questions/520288/... заключается в использовании переопределения OnResultExecuted в конце выполнения часов.
Когда вы вернетесь
ActionResponse.Success(arr.Select(x => func(x)).ToJson();
то есть. некоторый ленивый оператор LINQ в результате вашего действия, он будет вычисляться после того, как действие "выполнено" (исполнение функции "func" не будет считаться в течение времени выполнения действия).
У меня эта неприятная ошибка, и я не мог понять, почему мое действие "время выполнения" составляет 100 мс, хотя веб-запрос выполняет 10 секунд. Измененный код ниже.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace SW
{
public class StopwatchAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var stopwatch = new Stopwatch();
filterContext.HttpContext.Items["Stopwatch"] = stopwatch;
stopwatch.Start();
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var stopwatch = (Stopwatch)filterContext.HttpContext.Items["Stopwatch"];
stopwatch.Stop();
var httpContext = filterContext.HttpContext;
var response = httpContext.Response;
response.AddHeader("X-Runtime", stopwatch.Elapsed.TotalMilliseconds.ToString());
}
}
}
Ответ 3
Почему бы не взглянуть на модуль производительности страницы из сообщества Rhino?
Ответ 4
Похоже, вы на порядок. Вы уверены, что правильно читаете результат? Попробуйте использовать свойство Stopwatch.ElapsedMilliseconds
.