Medición del rendimiento de ASP.NET MVC 3

He construido un servicio JSON en ASP.NET MVC 3 y quiero poder medir el tiempo de ejecución de las acciones en mi aplicación (quiero que registre automáticamente las acciones lentas).

Por lo tanto esto se veía genial; http://coderjournal.com/2010/10/timing-the-execution-time-of-your-mvc-actions/ (También se ha mencionado en lugares aquí en el desbordamiento de stack)

El problema es que obtengo mediciones que DEBEN estar equivocadas con este método; He agregado otro cronómetro que comienza lo primero en la acción y se detiene justo antes de la devolución.

Ejemplo:

  • Cronómetro dentro del método => 10 ms (aquí se omite la serialización a json, por lo que puedo entender que es más corto que la realidad)
  • Atributo de cronómetro (código arriba) => 676ms
  • Firefox dice que la solicitud tomó => 70ms .

Creo que Firefox tiene la hora correcta aquí (pero incluye la descarga, por lo que es un poco grande), pero quiero entender por qué el código de atributo no funciona, ¿alguna idea para esto?

Es posible que esta no sea la razón por la que muestra ese largo tiempo de ejecución, pero ese atributo no funcionará correctamente con mvc 3 cuando tenga varias solicitudes a la vez.

En versiones anteriores de ASP.NET MVC, los filtros de acción se crean por solicitud, excepto en algunos casos. Este comportamiento nunca fue un comportamiento garantizado, sino simplemente un detalle de implementación y el contrato para los filtros era considerarlos sin estado. En ASP.NET MVC 3, los filtros se almacenan en caché de forma más agresiva. Por lo tanto, cualquier filtro de acción personalizado que almacene incorrectamente el estado de la instancia podría estar roto.

Recomiendo crear un nuevo cronómetro en OnActionExecuting y guardarlo en HttpContext.Current.Items ; luego puede recuperarlo en OnActionExecuted e imprimir el resultado.

El enfoque más correcto además de responder https://stackoverflow.com/a/5823555/504082 es usar la anulación OnResultExecuted al final de la ejecución del reloj. Cuando regreses

 ActionResponse.Success(arr.Select(x => func(x)).ToJson(); 

es decir, alguna instrucción LINQ perezosa como resultado de su acción, se calculará después de que la acción se haya “ejecutado” (la función ‘func’ ejecución no se contará para el tiempo de ejecución de la acción). Tengo este error desagradable y no pude entender por qué mi “tiempo de ejecución” de acción es de 100 ms, aunque la solicitud web se ejecuta en 10 segundos. Código modificado a continuación.

 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()); } } } 

¿Por qué no echar un vistazo al módulo de rendimiento de la página de Rhino commons?

Parece que estás fuera por un orden de magnitud. ¿Estás seguro de que estás leyendo el resultado correctamente? Intente usar la propiedad Stopwatch.ElapsedMilliseconds .