c# optimization performance

Acelerando C#



optimization performance (17)

Además de las mejores prácticas de codificación enumeradas anteriormente, incluido el uso de StringBuilders cuando corresponda y elementos de esa naturaleza.

Recomiendo usar una herramienta de creación de perfiles de código como ANTs Profiler de RedGate. Después de tomar los pasos estándar para la optimización, descubrí que al usar Profiler I puedo optimizar aún más mi código al identificar rápidamente el área o los códigos que son más afectados por la aplicación.

En realidad, se trata de dos preguntas, pero son muy similares, y para hacerlo simple, pensé que simplemente las juntaría:

  • En primer lugar : dado un proyecto C # establecido, ¿cuáles son algunas formas decentes para acelerarlo más allá de la simple optimización en código?

  • En segundo lugar : al escribir un programa desde cero en C #, ¿cuáles son algunas buenas formas de mejorar el rendimiento en gran medida?

Por favor, manténgase alejado de las técnicas de optimización generales a menos que sean específicas de C # .

Esto ya se ha pedido para Python , Perl y Java .


Desafortunadamente, relativamente pocas optimizaciones son específicas del idioma. Lo básico se aplica en todos los idiomas:

  • Mida el rendimiento contra cargas realistas
  • Tener objetivos claramente definidos para guiarte
  • Use un buen generador de perfiles
  • Optimizar arquitectura / diseño relativamente temprano
  • Solo micro-optimize cuando tienes un problema comprobado

Cuando hayas demostrado que necesitas una micro-optimización, el generador de perfiles tiende a hacer obvio qué buscar, como evitar el boxeo y las llamadas virtuales.

Oh, hay una cosa que puedo pensar que es específica de .NET: si necesita hacer una llamada con frecuencia y está utilizando el reflejo, convierta esas llamadas en delegados .

EDITAR: Las otras respuestas que sugieren usar genéricos y StringBuilder, etc. son, por supuesto, correctas. Yo (probablemente erróneamente) supuse que esas optimizaciones eran demasiado "obvias";)


La parte superior de mi cabeza:

  • Reemplazar variantes no genéricas de clases de contenedor por sus contrapartes genéricas
  • Reducir el boxeo / unboxing. Específicamente, use genéricos siempre que sea posible y generalmente evite pasar tipos de valores como object .
  • Para los cuadros de diálogo que usan muchos controles dinámicos: suspenda el dibujo hasta después de insertar todos los controles utilizando SuspendLayout / ResumeLayout . Esto ayuda especialmente cuando se usan contenedores de diseño.

Mucha lentitud está relacionada con el acceso a la base de datos. Haga que sus consultas a la base de datos sean eficientes y hará mucho por su aplicación.


NGEN ayudará con algún código, pero no se base en él.

Personalmente, si su diseño es malo / lento, no hay mucho que pueda hacer.

La mejor sugerencia en tal caso es implementar alguna forma de almacenamiento en caché de tareas costosas.


No uses para mucha reflexión.


Perfile su código. Entonces, al menos, puedes entender dónde puedes mejorar. Sin perfiles estás disparando en la oscuridad ...



Una cosa simple es asegurarse de que su configuración de compilación esté configurada en "Liberar". Esto habilitará optimizaciones y eliminará la información de depuración, reduciendo su ejecutable.

Más información en MSDN si es necesario.


Use Ngen.exe (debe venir incluido con Visual Studio).

http://msdn.microsoft.com/en-us/library/6t9t5wcf(VS.80).aspx

Native Image Generator (Ngen.exe) es una herramienta que mejora el rendimiento de las aplicaciones administradas. Ngen.exe crea imágenes nativas, que son archivos que contienen código máquina compilado específico del procesador, y las instala en la caché de imágenes nativas en la computadora local. El tiempo de ejecución puede usar imágenes nativas de la memoria caché en lugar de usar el compilador just-in-time (JIT) para compilar el ensamblado original.


Use un perfilador de calidad decente y determine dónde están sus cuellos de botella.

Luego comienza a preguntar cómo mejorar el rendimiento.

Cualquier persona que haga afirmaciones generales como "evite la reflexión" sin entender tanto su perfil de rendimiento como el dominio de su problema debe filmarse (o al menos reeducarse). Y dado el tamaño del panorama de .Net, no tiene sentido hablar sobre la optimización de C #: ¿estamos hablando de WinForms, ASP.Net, BizTalk, Workflow, SQL-CLR? Sin el contexto, incluso las pautas generales pueden ser, en el mejor de los casos, una pérdida de tiempo.

Considere también lo que quiere decir con "acelerarlo" y "mejorar el rendimiento". ¿Quiere decir una mayor eficiencia de recursos o un menor tiempo de espera percibido para un usuario final (suponiendo que exista)? Estos son problemas muy diferentes para resolver.

Dado el foro, me siento obligado a señalar que existe una cobertura bastante buena sobre estos temas en Code Complete. No mente específica de C #. Pero eso es algo bueno. Tenga en cuenta que las micro-optimizaciones específicas del idioma podrían ser incluidas en la próxima versión del compilador que esté utilizando, y si la diferencia entre for y foreach es una gran cosa para usted, probablemente esté escribiendo C ++ de todos modos, ¿no?

[Me gustó el Analizador de ANTS de RedGate, pero creo que podría mejorarse]

Con eso fuera del camino, algunos pensamientos:

  • Utilice el tipo (SomeType) en lugar de instance.GetType () cuando sea posible
  • Use foreach de preferencia para
  • Evitar el boxeo
  • Hasta (creo) 3 cuerdas está bien hacer StringA + StringB + StringC. Después de eso deberías usar un StringBuilder

Utilice la composición en lugar de la herencia, limite el boxeo / unboxing, use colecciones genéricas, use bucles foreach en lugar de {} con un contador y libere recursos con el patrón Dispose estándar.

Estos están cubiertos en detalle en el excelente libro Effective C #.


  • Use StringBuilder en lugar de mucha concatenación de cadenas. Los objetos de cadena son atómicos, y cualquier modificación (anexa, superior, relleno, etc.) en realidad genera un objeto de cadena completamente nuevo en lugar de modificar el original. Cada cadena nueva debe asignarse y, finalmente, recogerse la basura.

  • Una generalización de la declaración anterior: intente reutilizar objetos en lugar de crear montones y montones de ellos. La asignación y la recolección de basura pueden ser fáciles de hacer, pero afectan su rendimiento.

  • Asegúrese de usar las bibliotecas provistas de Microsoft para la mayoría de las cosas. Las clases proporcionadas por el Framework a menudo usan características que no están disponibles o son difíciles de acceder desde su propio código C # (es decir, hacer llamadas a la API nativa de Windows). Las bibliotecas integradas no siempre son las más eficientes, pero la mayoría de las veces.

  • Escribir aplicaciones asíncronas nunca ha sido tan fácil. Mire cosas como la clase BackgroundWorker.

  • Intenta no definir Structs a menos que realmente los necesites. Las variables de instancia de clase contienen una referencia a la instancia real, mientras que las variables de instancia de estructura contienen una copia por separado.


Esto es cierto para cualquier idioma, no solo para C #

  1. Para una aplicación existente, no haga nada hasta que sepa lo que lo hace lento. En mi humilde opinión, esta es la mejor manera.

  2. Para las nuevas aplicaciones, el problema es cómo se les enseña a los programadores. Se les enseña a hacer montañas con toperas. Después de que hayas optimizado algunas aplicaciones con esto, estarás familiarizado con el problema de lo que llamo "generalidad galopante", capa tras capa de "abstracción", en lugar de simplemente preguntarte qué es lo que el problema requiere. Lo mejor que puedes esperar es correr detrás de ellos, diciéndoles cuáles son los problemas de rendimiento que acaban de presentar, para que puedan eliminarlos a medida que avanzan.


Para Windows Forms en XP y Vista: active el doble búfer en todos los ámbitos. Causa problemas de transparencia, por lo que definitivamente querrá probar la IU:

protected override System.Windows.Forms.CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle = cp.ExStyle | 0x2000000; return cp; } }



Almacenamiento en caché de elementos que resultan de una consulta:

private Item _myResult; public Item Result { get { if (_myResult == null) { _myResult = Database.DoQueryForResult(); } return _myResult; } }

Es una técnica básica que frecuentemente se pasa por alto por los programadores que comienzan, y una de las maneras MÁS FÁCILES de mejorar el rendimiento en una aplicación.

Respuesta portada de una pregunta que fue descartada como una estafa.