2011-04-27 14 views
13

Tengo curiosidad ¿cómo funciona un perfilador de C# típico?¿cómo funciona un perfilador C#?

¿Hay ganchos especiales en la máquina virtual?

¿Es fácil escanear el código de bytes para las llamadas de función e inject calls para iniciar/detener el temporizador?

¿O es realmente difícil y es por eso que la gente paga por las herramientas para hacer esto?

(como nota al margen encuentro un poco interesante bec es tan raro - Google pierde el barco por completo de la búsqueda "how does a c# profiler work?" no funciona en todos - los resultados están a punto de aparatos de aire acondicionado ...)

+3

espero a Jon Skeet. –

+2

Este artículo tiene mucha información buena: http://msdn.microsoft.com/en-us/magazine/cc301725.aspx. También http://msdn.microsoft.com/en-us/library/bb384547.aspx –

+0

En general, muchos perfiladores toman instantáneas muy frecuentes de la pila para ver dónde se encuentra actualmente. Luego construyen estadísticas usando esas instantáneas. Por supuesto, existe la clara posibilidad de que este no sea el caso con C#, así que tómalo con un grano de sal. –

Respuesta

3

Hay un CLR Profiler gratuito de Microsoft, versión 4.0.

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

Por cierto, hay una sección agradable en el doc CLR Profiler que describe cómo funciona, en detalle, página 103. Hay fuente como parte de distribución.

+3

Eso es bueno saberlo, pero no tiene nada que ver con la respuesta a la pregunta. –

+1

+1 para contrarrestar a los infractores. Usted proporcionó una respuesta directa a la pregunta de OP. –

+0

CLR Profiler viene con su fuente, si alguien está interesado en cómo funciona. –

1

1) No existe el término "típico". Las personas recopilan información de perfil por varios medios: muestrean la PC, inspeccionan los rastros de pila, capturan cuentas de ejecución de métodos/declaraciones/instrucciones compiladas, insertan sondas en el código para recopilar conteos y opcionalmente llaman a contextos para obtener datos de perfil en un contexto de llamada base. Cada una de estas técnicas podría implementarse de diferentes maneras.

2) Hay perfiles "C#" y perfiles "CLR". En el mundo de MS, podría perfilar CLR y traducir las ubicaciones de las instrucciones CLR al código C#. No sé si Mono usa el mismo conjunto de instrucciones CLR; si no lo hicieron, entonces no podría usar el perfilador MS CLR; tendrías que usar un perfilador Mono IL. O bien, podría instrumentar código fuente C# para recopilar los datos de creación de perfiles y luego compilar/ejecutar/recopilar esos datos en MS, Mono o el compilador personalizado compatible con C# de alguien, o C# ejecutándose en sistemas integrados como WinCE donde el espacio es valioso y características como CLR-built-ins tienden a quedar fuera.

Una forma de instrumentar el código fuente es utilizar las transformaciones de fuente a fuente, para asignar el código desde su estado inicial al código que contiene el código de recopilación de datos, así como el programa original. Este paper on instrumenting code to collect test coverage data muestra cómo se puede usar un sistema de transformación de programa para insertar sondeos de cobertura de prueba insertando instrucciones que establecen indicadores booleanos específicos de bloque cuando se ejecuta un bloque de código. Un cuenta-perfilador sustituye las instrucciones de incremento de contador para esas sondas. Un generador de perfiles de tiempo inserta cómputos de reloj/instantánea/delta para esas sondas. Nuestro C# Profiler implementa los perfiles de recuento y tiempo para el código fuente de C# en ambos sentidos; también recoge los datos del gráfico de llamadas mediante el uso de sondeos más sofisticados que recopilan la ruta de ejecución. Por lo tanto, puede producir datos de tiempo en gráficos de llamadas de esta manera. Este esquema funciona en cualquier lugar donde puedas obtener un valor de tiempo de resolución medio aceptable.

3

¿Es fácil para escanear el código de bytes para llamadas a funciones e inyectar llamadas a de arranque/parada del temporizador?

¿O es realmente difícil y es por eso que personas pagan herramientas para hacer esto?

Inyectar las llamadas es tan difícil que se necesitan herramientas para hacerlo.

No solo es difícil, es una forma muy indirecta de encontrar cuellos de botella. La razón es que un cuello de botella es una o una pequeña cantidad de declaraciones en su código que son responsables de un buen porcentaje de tiempo que se gasta, tiempo que podría reducirse significativamente, es decir, no es realmente necesario, es decir, es un desperdicio. SI puede indicar el tiempo medio de inclusión de una de sus rutinas (incluido el tiempo de IO), y SI puede multiplicarlo por cuántas veces se ha llamado, y dividir por el tiempo total, puede decir en qué porcentaje de tiempo toma de rutina Si el porcentaje es pequeño (como 10%) es probable que tenga problemas más grandes en otro lugar. Si el porcentaje es mayor (como 20% a 99%), podría tener un cuello de botella dentro de la rutina. Así que ahora tiene que cazar dentro de la rutina para ello, mirando las cosas que llama y cuánto tiempo toman tomar. También quiere evitar confundirse con la recursión (el bugaboo de los gráficos de llamadas).

Hay perfiladores (como Zoom para Linux, Shark, & otros) que funcionan en un principio diferente. El principio es que hay una pila de llamadas a funciones, y durante todo el tiempo que una rutina es responsable (ya sea de trabajar o esperar que otras rutinas hagan el trabajo que solicitó) es en la pila. Entonces, si es responsable del 50% del tiempo (por ejemplo), esa es la cantidad de tiempo que está en la pila, independientemente de cuántas veces se haya llamado o cuánto tiempo tomó por llamada. No solo está la rutina en la pila, sino que las líneas específicas de código que cuestan el tiempo también están en la pila. No necesita buscarlos. Otra cosa que no necesita es precisión de medición. Si tomó 10,000 muestras de pila, las líneas culpables se medirán a 50 +/- 0.5 por ciento. Si tomó 100 muestras, se medirían como 50 +/- 5 por ciento. Si tomó 10 muestras, se medirían como 50 +/- 16 por ciento. En todos los casos los encuentra, y ese es su objetivo. (Y la recursividad no importa. Todo lo que significa es que una línea determinada puede aparecer más de una vez en una muestra de pila determinada)

Sobre este tema, hay mucha confusión. En cualquier caso, los perfiladores que son más efectivos para encontrar los cuellos de botella son los que toman muestras de la pila, en la hora del reloj de pared e informan el porcentaje por línea. (Esto es fácil de ver si cierta myths about profiling se ponen en perspectiva.)

+0

+1! Parece que deberíamos escribir un nuevo generador de perfiles para dotNET con este concepto simple en mente. En lo que respecta a la IU, estaba pensando en WinDirStat, solo mostramos el tiempo invertido en varios métodos, agrupados por espacios de nombres.clases. – GregC

+0

@GregC: escribí hace un siglo. Acabo de hacer que recoja muestras de pila cuando presiona ambas teclas de mayúsculas. Luego tuve una vista de mariposa enfocada en una línea de código, no en una función. Comenzó en una línea con un% alto, y se podía pasar a las líneas vecinas arriba y abajo. Hizo una buena demostración, pero descubrí que para un trabajo serio, no podía superar el método puramente manual, por una serie de razones, así que lo dejé descansar. En cualquier caso, si haces algo similar a Zoom, obtendrás un ganador, en mi humilde opinión. –

+0

@GregC: Lo que quiero decir con no superar el método manual es, seguro, es más difícil recolectar varias muestras manualmente, elegir una línea "caliente" y ver el árbol hacia abajo y hacia arriba desde esa línea. Eso es un poco tedioso Pero si algo me llama la atención, tomo más muestras hasta que vuelva a ocurrir, y luego lo estudio para narrar qué estaba haciendo el programa y por qué. Esto puede significar mirar otros datos además de la pila. Cuando lo entiendo completamente, puedo decir si realmente es un desperdicio y puede ser reemplazado con algo mejor. Por lo tanto, encontrar altas líneas% es solo una introducción al proceso. –

1

Este es un enlace a un extenso artículo que trata sobre los dos métodos de instrumentación y de muestreo:

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

+0

Lo que dice sobre el muestreo es solo el modelo gprof, de casi 30 años. Los samplers modernos hacen mucho mejor. –