2009-02-15 10 views
7

Acabo de heredar un proyecto C# que se ralentiza y tendrá que comenzar a optimizarlo. Lo que quería hacer primero es aprender un poco más acerca de la creación de perfiles/optimización ya que no tenía que hacerlo antes. Entonces, la pregunta es ¿dónde empiezo, qué libros/blogs/articulos puedo leer?¿Cuáles son algunos recursos que puedo usar para aprender a perfilar/optimizar?

Sé de los perfiles de .net como ANTS profiler y demás, pero no tengo idea de cómo usarlos de manera eficiente. Realmente no lo he usado, solo déjalo correr en algunas aplicaciones de muestra para jugar con la salida.

+0

Juega con los perfiladores si quieres, pero para resolver el problema, haz lo siguiente: http://stackoverflow.com/questions/550109/what-are-some-resources-i-can-use-to-learn- profiling-optimizing/575417 # 575417 –

Respuesta

14

Hay dos pasos para optimizar el código.

Primero, necesita saber qué es lento. Eso es perfilar, y, como es de suponer, un perfilador se utiliza comúnmente para esto. La mayoría de los perfiladores generalmente son fáciles de usar. Ejecuta su aplicación a través de un generador de perfiles, y cuando finaliza, el generador de perfiles le mostrará cuánto tiempo pasó en cada función, exclusiva (esta función sin contar el tiempo dedicado a la función invocada desde allí) e inclusive (tiempo empleado en este función, incluidas las llamadas a función infantil).

En otras palabras, obtienes un gran árbol de llamadas, y solo tienes que buscar los números grandes. Por lo general, tiene muy pocas funciones que consuman más del 10% del tiempo de ejecución. Así que ubique estos y sepa qué para optimizar.

Tenga en cuenta que un perfilador no es necesario ni, necesariamente, el mejor enfoque. Un enfoque notablemente simple, pero efectivo, es simplemente ejecutar el programa en un depurador y, en unos pocos tiempos casi aleatorios, detener la ejecución y observar la pila de llamadas. Haga esto solo un par de veces, y tiene una muy buena idea de dónde se está gastando su tiempo de ejecución. @Mike Dunlavey que comentó en esta respuesta ha descrito este enfoque en profundidad en otros lugares.

Pero ahora que sabe dónde se está gastando el tiempo de ejecución, entonces viene la parte difícil, cómo para optimizar el código.

Por supuesto, el enfoque más efectivo suele ser el de alto nivel. ¿El problema tiene que ser resuelto de esta manera? ¿Tiene que ser resuelto en absoluto?¿Pudo haber sido resuelto de antemano y el resultado almacenado en caché para que pudiera entregarse instantáneamente cuando el resto de la aplicación lo necesitara? ¿Hay algoritmos más eficientes para resolver el problema?

Si puede aplicar tales optimizaciones de alto nivel, hágalo, vea si eso mejoró el rendimiento lo suficiente, y si no, vuelva a generar el perfil.

Tarde o temprano, es posible que tenga que sumergirse en más optimizaciones de bajo nivel. Sin embargo, este es un territorio complicado. Las computadoras de hoy en día son bastante complejas y el rendimiento que obtiene de ellas no es directo. El costo de una rama o una llamada a una función puede variar ampliamente según el contexto. Agregar dos números juntos puede llevar de 0 a 100 ciclos de reloj dependiendo de si ambos valores ya estaban en los registros de la CPU, qué más se está ejecutando en ese momento, y un número de otros factores. Entonces la optimización en este nivel requiere (1) una buena comprensión de cómo funciona la CPU, y (2) mucha experimentación y mediciones. Puede hacer fácilmente un cambio que piensa será más rápido, pero debe estar seguro, así que mida el rendimiento antes y después del cambio.

Hay algunas reglas generales que a menudo pueden ayudar a optimizaciones de guía:

de E/S es caro. Las instrucciones de la CPU se miden en fracciones de un nanosegundo. El acceso a la RAM es del orden de decenas a cientos de nanosegundos. Un acceso al disco duro puede tomar decenas de mili segundos. Muy a menudo, la E/S será lo que está ralentizando su aplicación. ¿Su aplicación realiza pocas lecturas de E/S grandes (lea un archivo de 20 MB en una gran porción) o innumerables pequeñas (lea los bytes 2,052 a 2073 de un archivo y luego lea un par de bytes de otro archivo)? Menos lecturas grandes pueden acelerar su E/S en un factor de varios miles.

Los fallos de página también implican accesos al disco duro. Las páginas en memoria se deben insertar en el archivo de paginación, y las paginadas se deben volver a leer en la memoria. Si esto sucede mucho, va a ser lento. ¿Puedes mejorar la localidad de tus datos para que se necesiten menos páginas al mismo tiempo? ¿Puede simplemente comprar más RAM para la computadora host para evitar tener que sacar datos de la página? (Como regla general, el hardware es barato. Actualizar la computadora es una optimización perfectamente válida, pero asegúrese de que la actualización haga la diferencia. Las lecturas de discos no serán mucho más rápidas al comprar una computadora más rápida. Y si todo encaja en la RAM en su sistema anterior, no tiene sentido comprar uno con 8 veces más RAM)

Su base de datos también se basa en los accesos al disco duro. Entonces, ¿puede salirse con la tarea de almacenar en caché más datos en la memoria RAM y solo ocasionalmente escribirlos en la base de datos? (Por supuesto que hay un riesgo allí. ¿Qué sucede si la aplicación falla?

Y luego está todo el mundo favorito, enhebrado. Una CPU moderna tiene entre 2 y 16 núcleos de CPU disponibles. ¿Los está usando todos? usándolas? ¿Hay operaciones de ejecución prolongada que se pueden ejecutar de forma asíncrona? La aplicación inicia la operación en una secuencia separada, y luego puede reanudar la operación normal de forma instantánea, en lugar de bloquearla hasta que la operación se complete.

Así que básicamente , utilice el generador de perfiles para comprender su aplicación. ¿Cómo gasta su tiempo de ejecución, dónde se está gastando? ¿Es un problema el consumo de memoria? ¿Cuáles son los patrones de E/S (tanto en el disco duro y acceso a la red, así como cualquier otro tipo de E/S)? ¿La CPU está funcionando todo el tiempo o está inactiva esperando eventos externos, como E/S o temporizadores?

Y luego comprenda todo lo que pueda sobre la computadora en la que se está ejecutando. Comprenda qué recursos tiene disponible (caché de CPU, núcleos múltiples) y qué significa cada uno de ellos para el rendimiento.

Todo esto es bastante vago, porque los trucos para optimizar un gran servidor de base de datos van a ser muy diferente de lo que haría para optimizar algún gran algoritmo de reducción de número.

+1

@jalf: este es un buen resumen de performance-analysis-as-a-big-subject. Me gusta pensar que es un tema pequeño. El muestreo de la pila de llamadas (lo hago manualmente) dice dónde está el desperdicio, de forma rápida y precisa. –

3

Si está familiarizado y ya ha comprado ANTS (un perfilador muy fino), entonces vaya al here para obtener un tutorial rápido para ponerlo en funcionamiento.

4

Estoy tomando un curso de pregrado (un tema es Análisis de rendimiento) y el texto recomendado es The Art of Computer Systems Performance Analysis: Techniques for Experimental Design, Measurement, Simulation, and Modeling. Es una especie de biblia sobre el tema y puede ser un poco exagerado.

+0

exagerado es bueno para esas noches de insomnio donde solo tienes que leer un poco de texto seco en el análisis del rendimiento para sacarte de bien :) thx – LDomagala

+0

@LDomagala ¡Amén! – Kredns

2

Si tiene Visual Studio Team System sugiere emplear el Perfil que contiene.
Está en "Analizar-> Perfilador"
Usar este perfilador es realmente simple. Puedes simplemente sumergirte y ver lo que haces de él. La práctica práctica es mejor que cualquier artículo o libro que vayas a leer al respecto.

Encontrar sus primeros cuellos de botella es fácil con solo unos pocos clics. Resolverlos podría ser un poco más complicado, pero de nuevo, Optimizar el código es solo una cuestión o práctica y experiencia.

1

Lee Rico Mariani's blog. Antes de ser promovido, era un tipo de tuning de rendimiento para .Net. Las entradas más antiguas en su blog tienen muchísimos buenos consejos. Comenzaría cerca del principio y seguiría adelante.

Eso, más los artículos que ya ha encontrado (especialmente el first one) deberían ayudarle a comenzar.

0

Esto no te ayudará mucho en C#, pero las herramientas OS X Shark (vienen con las herramientas de desarrollador de Apple) son las mejores herramientas de creación de perfiles que he encontrado. ¡Casi divertido de usar!

En cuanto a la creación de perfiles, hay dos formas de acercamiento. En primer lugar, debe comprender el software. Las estructuras de datos especialmente. No comience a optimizar a menos que lo entienda primero.

En segundo lugar, deberá medir (que parece que está a punto de hacer). He sido engañado por mi instinto visceral casi siempre; lugares que consideraría secundarios son los que toman el tiempo. Esto también significa que cuando estás optimizando siempre estás optimizando para un cierto conjunto de casos de prueba que ejecutas. La selección de tales casos es importante.

1

Hay perfiladores y herramientas de análisis de rendimiento, pero mientras que usted está tratando de encontrar/comprar/instalar/aprender uno, sólo tratan de un truco viejo ...

ejecutar la aplicación bajo el IDE, y mientras está siendo lento, presiona el botón "Pausa" y pregúntale qué está haciendo, y por qué. La mejor manera de responder esto es leyendo la pila de llamadas.

Si es varias veces más lento de lo que debería, como 10 veces, eso significa que está gastando el 90% de su tiempo haciendo algo innecesario, y que es la probabilidad de que lo atrape haciéndolo. Si repite esto varias veces, puede confirmar sus sospechas con la precisión que desee.

Así que no necesita una lupa cara/popular pero difusa.

Por lo tanto, encontrar el motivo de la lentitud no es la parte difícil, y generalmente hay varios.

La parte difícil es que, después de haber arreglado algunas "frutas bajas", probablemente tendrá que enfrentar el hecho de que la razón principal de la lentitud es el exceso de diseño.

Buena suerte.

1

He usado perfiladores antes, pueden ser útiles, pero puede obtener mucha ayuda simplemente al crear una clase de tipo de cronómetro singleton y hacer "clic" (hacer que imprima la hora desde el último clic y qué se acaba de hacer que tomó ese tiempo) antes y después de los métodos que crees que pueden ser problemáticos.

Si la velocidad es un problema en toda la aplicación, es probable que no va a ser capaz de hacer demasiado al respecto, pero es posible que pueda hacer algunos cambios ...

Busque bucles internos . Estas son muertes de rendimiento. Un bucle interno puede ser causado por algo tan simple como indexar en una lista enlazada, o hacer una ordenación por inserción en una lista basada en arreglos.(Una vez que tenía un cuadro de lista que tardaba entre 10 y 20 minutos en llenarse con decenas de miles de entradas, aunque eran demasiadas entradas, la peor parte era que estaba ordenando insertando cada entrada en una lista de matriz).

Busque los casos en los que realiza operaciones largas basadas en presionar teclas. Esto casi siempre debe hacerse fuera del hilo principal.

Ni siquiera PIENSAS en optimizar cosas como números de clases o con qué frecuencia se crean instancias, concatenación de cadenas (fuera de bucles), anulando variables o cualquiera de las otras estrategias tontas que parecen que deberían ayudar. Intenté algunas y siempre terminé sintiéndome tonto cuando en realidad disminuía la velocidad porque no era tan inteligente como el tiempo de ejecución en la mayoría de las cosas.

1

Me gustaría descargar algunas de las herramientas de creación de perfiles disponibles (pruebas gratuitas) y comenzar a usarlas.

He usado jetbrains, y hay otros. (ants for example, devpartner y a MS one?, atomatedqa, etc.) No debería tener demasiados problemas para ejecutarlos. Tienen informes que le brindan mucha información y puede aprender bastante rápido simplemente usando las aplicaciones.

Probablemente cualquiera de ellos te ayude y es bueno usar las pruebas. A continuación, puede dejar de lado la decisión de comprar la herramienta o comprar la que le resultó más útil/más fácil de usar. En general, ahorran mucho tiempo y vale la pena el dinero, aunque algunos pueden ser costosos. (Tengo dificultades con los que están en el extremo superior cuando hay herramientas muy buenas por mucho menos dinero)

Es posible que encuentre algunos problemas graves de rendimiento el primer día que los instale y los ejecute. Sé que lo hice.

buena suerte.

acaba de descargar algunas herramientas y comenzar a ejecutar su aplicación.

EDIT:

En cuanto a libros y el aprendizaje - básicamente la mejor manera de aprender acerca de problemas con el código es encontrar mal código. Muchas veces haciendo inspecciones con desarrolladores experimentados será útil.

como ejemplo: Creo que Joel escribió un artículo camino de vuelta sobre él hizo algo así como

for (int i = 0; i < strlen (algunos de cuerda); i ++)

que es bastante obvio que va a llamar a strlen (caro) en cada iteración del ciclo.

Tendrá que mirar algo del código después de que el generador de perfiles le indique dónde se está gastando el tiempo y ver si el código se puede arreglar fácilmente con cosas simples como eso, o se deben hacer cambios en el diseño de los algoritmos.

0

Ya ha golpeado el clavo en la cabeza con el Perfilador. Todos ellos, al menos todo lo que he usado, siguen la misma metodología básica. Selecciona el ejecutable y luego ejecuta la aplicación.

Lo que hace con la salida es encontrar los métodos que requieren más tiempo.l Esto no es todo, pero usted pidió una buena manera de aprender a optimizar el código, por lo que las rutinas de larga ejecución son un buen lugar para comienzo. ANTS, que usted mencionó, mostrará de manera predeterminada las rutinas de larga ejecución, como la mayoría, si no todas, otras.

Puede excluir los métodos del contenedor, como Main(), a menos que tenga muchos códigos allí (poco probable).

En general, me parece más residuos en tres áreas:

  1. Loops
  2. recursividad
  3. Red de latencia

Zona # 3, de la base de datos, es generalmente fácil de detectar si también perfilará su base de datos, ya que verá la cantidad de visitas. La mejor manera de reducir la latencia de la red, ya sea de base de datos o no (llamadas de servicio, por ejemplo), es comunicarse en mensajes en lugar de CRUD. No consulte cada tabla, una a la vez. Desafortunadamente, la solución a menudo requiere enlatar partes de muchas capas de datos comunes.

La recursividad y los bucles son problemas muy similares. Si quieres golpear el dinero, primero golpea el bucle interno.

En .NET, también puede aprender mucho sobre optimización aprendiendo IL básico y examinando el IL de sus aplicaciones a través de herramientas como Reflector. Un poco de pérdida de tiempo, si esta no es la parte principal de la descripción de su trabajo, o algo que probablemente quiera dedicar a su carrera futura. Ser bombero paga bien, pero ser un programador de mantenimiento puede ser muy aburrido.

Hay solo un par de libros sobre optimización y creación de perfiles de aplicaciones .NET. El que tiene optimismo en el título. El libro de depuración para .NET tiene cierta información sobre Profiling, pero no es muy profundo. Sin embargo, es un gran libro para leer para la optimización, ya que muchos problemas que causan errores también aparecerán en sus viajes de optimización.

Cuestiones relacionadas