Red de conocimiento informático - Material del sitio web - Cómo desarrollar software de alto rendimiento con c#

Cómo desarrollar software de alto rendimiento con c#

Esto implica dos aspectos:

Si compara el problema de usar C# para desarrollar software de alto rendimiento verticalmente, de hecho, C# no tiene la ventaja. un lenguaje de quinta generación es una biblioteca de clases que utiliza mucha reflexión de referencia, especialmente las características del lenguaje intermedio (portabilidad), que tiene una gran pérdida en términos de su propio rendimiento. Por supuesto, se puede entender que C #. intercambia rendimiento por legibilidad del código características como facilidad de uso y portabilidad. Por lo tanto, en comparación con C/CPP, C# en sí no tiene ninguna ventaja de rendimiento, por lo que si hablamos de rendimiento del lenguaje, solo lo comparamos con PHP/JAVA, y realmente no puede lograr una gran ventaja en rendimiento. Esto también es una debilidad en la aplicación de controladores/monolitos/tarjetas gráficas/sistemas en tiempo real. Esta es una de las razones por las que C# está posicionado en la industria del software de aplicaciones, en lugar de en las industrias de controladores/monolíticos/sistemas en tiempo real. Por lo tanto, si se compara verticalmente el software de alto rendimiento, aún regresa a C/CPP. Por supuesto, debido a la dificultad del desarrollo y mantenimiento del ensamblador, este lenguaje solo se desarrolla y usa parcialmente en C/CPP (se usa como pegamento para mejorar). actuación).

Si solo hablamos dentro del alcance de C#, diferentes programadores tienen diferentes hábitos de desarrollo, y el rendimiento de cada módulo de cada programador también es alto o bajo. En este caso, el software de aplicación que lo implementa. misma función También hay diferencias en el rendimiento.

En cuanto a C#, en realidad no recomiendo la búsqueda excesiva del rendimiento, porque C# en sí no es un lenguaje de desarrollo de alto rendimiento, pero eso no significa que puedas ignorar el rendimiento como quieras (muchos programadores lo hacen). De esta manera, cuando dijo que su rendimiento era bajo, respondió que C # no era un lenguaje de alto rendimiento, si desea mejorar el rendimiento, use ensamblador. De hecho, este tipo de pensamiento es inaceptable, ¿por qué no? ¿Piensan en las mismas funciones? ¿Por qué algunas personas usan el mismo lenguaje C#, pero cuántos órdenes de magnitud son más altos que él? Una vez me tomó 2 horas y media procesar 16G de datos interactivos, pero también vi a alguien tardar dos días en procesar 14G de casi los mismos datos; esto es un problema de rendimiento dentro de C#.

De hecho, si desarrolla software de alto rendimiento y está limitado al lenguaje C#, entonces hay muchas cosas a las que debe prestar atención:

Multilineal o TPL: quiero decir, si lidiar con algunas Para tareas repetitivas simples, es posible que desee considerar el uso de subprocesos múltiples o bibliotecas paralelas de tareas para el desarrollo. No mejora el rendimiento, pero acorta el tiempo de trabajo del software. Por supuesto, se deben tener en cuenta diversas situaciones, como la obstrucción. Si no sabes cómo utilizarlo, alguien puede tener el efecto contrario. Los eventos o delegados también son un tipo de subprocesos múltiples, por lo que a veces utilizar el desarrollo de software basado en transacciones es una forma de mejorar la usabilidad del software. Entonces, si un programador nunca ha escrito un delegado o un evento, dice que entiende el subproceso múltiple, pero en realidad solo rasca la superficie. El subproceso múltiple está lejos de ser tan simple como ve.

Ampliación del conocimiento del dominio: este es en realidad un error que muchos programadores tienden a cometer. Mucha gente habla de algoritmos. De hecho, esto también es parte del algoritmo. Es obvio que existe Math.Power(5, 5) que puede realizar la quinta potencia de 5. También usas un bucle para multiplicar 5 por 5. ¿Puedes decir que el rendimiento es alto? Sé que este ejemplo es demasiado simple y muchos programadores no están dispuestos a admitirlo; de hecho, no se dan cuenta de que si son programadores de escuela primaria, aún no han estado expuestos al concepto de exponenciación. Ampliaré esta pregunta. , programadores No has entendido toda la industria empresarial en la que estás, por lo que este ejemplo no significa que no conozcas el lenguaje C# o la biblioteca de clases .net; significa que todavía hay áreas de conocimiento que no conoces. No conozco en la industria el software de destino. Y esto requiere mucha comunicación con el personal de la industria para aprender más sobre la industria; es por eso que muchas industrias requieren experiencia trabajando en industrias similares al momento de contratar.

Especificaciones a nivel de lenguaje - En todo el proceso de desarrollo de software, muchas veces puede deberse a limitaciones relacionadas con nuestro ciclo de desarrollo y otras restricciones relacionadas, lo que se convierte en una de nuestras excusas para no perseguir el rendimiento. La excusa de un ciclo de desarrollo corto puede tener sentido (a veces lo es), pero la excusa de los bajos costos de inversión no.

A nivel de lenguaje, además de estandarizar los hábitos de desarrollo básicos, a veces también es necesario estandarizar los requisitos de rendimiento. Por ejemplo, al conectar tablas, se deben usar tablas pequeñas para conectar tablas grandes y declaraciones que consumen rendimiento, como cadenas múltiples. conexiones, debe evitarse Al realizar el empalme, debe cambiarlo a StringBuilder en lugar de String. Cuando la base de datos obtenga datos, debe usar DataReader en lugar de DataAdapter, etc.

Uso reducido de memoria y CPU: mucha gente no entiende esto. ¿Por qué utilizar menos memoria o uso de CPU realmente mejora el rendimiento? De hecho, esto es para módulos. Si cada módulo ocupa mucha memoria y CPU, la integración final del software provocará fluctuaciones en la memoria y espera de las ruedas de la CPU. Es decir, básicamente desde la perspectiva de la operación del software, se considera el problema de asignación de recursos en todo el proceso de operación del software; por supuesto, esto es solo una estrategia, no necesariamente óptima, pero si no hay control, surgirán muchos problemas. I Mucha gente no estará de acuerdo con esto, pero de hecho, debería saber por qué a tantos programadores les gusta actualizar la CPU y agregar más memoria. Esto ilustra un problema. Pero los programadores que no lo toman en serio no tienen realmente control sobre sus propios programas.

Excepción inteligente: todos sabemos que el software no puede ejecutarse sin cometer errores. Si falla cada vez que comete un error, ¿cómo podemos hablar de rendimiento? Aumentar la solidez del programa implica aumentar el código del programa, lo que implica problemas de rendimiento. Pero lo que quiero decir aquí es que nuestra aplicación tiene un método de manejo de mecanismo de excepción unificado, en lugar de generar excepciones aleatoriamente en el código. Incluso si agrega try a cada módulo o detalle a cada método miembro, no significa necesariamente que el programa ensamblado no cometerá errores, por lo que generalmente permitimos que se generen excepciones en la capa central, por lo que si alguien en la capa central tiene una gran cantidad de Al utilizar la estructura de prueba, el rendimiento de esta capa central ya no es alto. ¿Por qué no trasladamos la excepción a la última capa (capa de escena/capa de llamada) para un procesamiento unificado? Entonces, cuando ves estructuras try anidadas directa o indirectamente, estos programadores no entienden el rendimiento en absoluto, ni entienden el mecanismo de excepción de C#. Es más, he visto una excepción lanzada en la rama catch de la estructura try: —If. no hay necesidades especiales, este tipo de programador está básicamente loco (en circunstancias normales, el rendimiento disminuirá cuando se detecte una excepción, y si se lanza una excepción después del llamado procesamiento, la estructura de prueba externa provocará Problemas de rendimiento nuevamente. Abajo, las excepciones pueden aparecer en la capa externa. Si no es por seguridad u otras razones especiales, hacerlo es puramente una forma de reducir el rendimiento. Es por eso que la capa central permite excepciones y rara vez usa la estructura try. )! Entonces, para el programa general, un buen diseño puede ayudarnos a mejorar el rendimiento general.

Buenos conocimientos y hábitos básicos: la mayoría de ellos todavía requieren que los programadores tengan cierta comprensión de la seguridad y el rendimiento de los subprocesos. La razón por la que lo enumero solo es porque hay demasiados malos hábitos que son convenientes para esto. Por ejemplo, la diferencia entre clases y estructuras. Si desea utilizar una gran cantidad de estructuras y la cantidad de datos es pequeña, debe utilizar estructuras en lugar de clases. Las estructuras son tipos de valores y se almacenan en la pila. Su rendimiento es conveniente y mejor que el de las clases. Sin embargo, para cantidades mayores, ocuparán un espacio de pila mayor, lo que es perjudicial para el software en general. cuando llegue el momento de usarlas. Use clases, no use estructuras cuando debería usar clases. ¿Cuántos programadores no están usando estructuras todavía? La sugerencia de Microsoft es considerar usar una estructura si el espacio de memoria es inferior a 16K (esto es solo una sugerencia, creo que este número ya es muy grande).

¿Cuántos programadores utilizan clases estáticas por conveniencia? De hecho, podemos construir inteligentemente clases estáticas en el núcleo, pero deben usarse con precaución en la programación periférica. No solo destruye la cohesión de la orientación a objetos, sino que también aumenta el uso de la memoria. ¡El rendimiento será seguro! ¿No tienes malos hábitos en ninguna de las categorías? Entonces debes tener el tercer tipo: el objeto o clase de diseño utiliza una gran cantidad de contenido legible sin diseño. Por ejemplo, si le da una identificación a una clase, obviamente es un número, pero habitualmente usa una cadena, y el nombre es "poco legible". Lo más común es la interacción de datos entre programas. como contenido de interacción binaria, debe convertirlo en una cadena y luego volver a convertirlo cuando lo use, etc. Si desea facilitar su propia "legibilidad", no mencione el problema de rendimiento. ¿Es conveniente que la computadora use binario o legibilidad en el sentido de su comprensión? A menudo veo esta situación: para facilitar el muestreo de datos, los programadores a menudo transfieren texto en lugar de archivos de datos binarios entre dos máquinas. De hecho, por motivos de rendimiento, utilizamos archivos binarios que los humanos realmente no pueden leer. Para leer este archivo, puedes desarrollar un software o herramienta para leerlo. ¿Por qué quieres hacer que la computadora gire en un círculo tan grande sólo porque puedes leer algo? Me interesa un ejemplo. ¿Debería almacenarse el campo de codificación del diseño de la base de datos en varchar(16) como una cadena hexadecimal o debería diseñarse directamente como bigint? Por lo tanto, cuando escriba código, utilice el procesamiento binario en lugar de dejar que el programa se adapte a usted. Esto mejorará el rendimiento de su programa.

Básicamente, el alto rendimiento tiene en cuenta consideraciones en muchas situaciones. En cuanto a los detalles, hay muchas cosas a las que se debe prestar atención. Para decirlo sin rodeos, los programas que diseñamos según la forma en que funcionan las computadoras son, por supuesto, mucho más rápidos que los diseñados según su manera. Entonces, algunos programadores antiguos, incluso cuando hacemos computación numérica en la nube, si x necesita multiplicarse por 16, escribirán x lt;lt;=4 en lugar de Todavía hay muchos de ellos,