Si ve un artículo en el que el idioma X es más rápido que el idioma Y, puede cerrar el artículo.





Con mi cerebro humanitario, siempre pensé de esta manera: si un programador sabe cómo hacer que tenga más rendimiento, entonces es necesario que tenga más rendimiento. Una solución productiva = la solución correcta. Un lenguaje de programación puede ser más lento que otro y, si resulta, el lenguaje de programación se desperdicia.



Bueno, seguro: si el desarrollador es un especialista en rendimiento, se ahogará por todas estas cosas, incluso si están equivocadas.



Naturalmente, todo esto es una tontería, pero no me corresponde a mí decírselo. Por lo tanto, Andrei Akinshin, desarrollador y matemático, candidato de las ciencias físicas y matemáticas, mantenedor de BenchmarkDotNet y perfolizador, autor del libro Pro .NET Benchmarking y simplemente un ingeniero muy, muy bueno, vino a nuestro podcast.





A continuación se muestran citas seleccionadas.



Es imposible prever todo en los puntos de referencia.



Un colega mío tuvo recientemente lo siguiente. Estaba programando por la mañana, todo estaba bien con él, todo funcionó rápido. En algún momento, todo comenzó a funcionar: Rider es lento, IDEA, el navegador, todo es lento. ¿No podía entender de ninguna manera cuál era el problema? Y luego me di cuenta. Trabajó en una computadora portátil negra que estaba junto a la ventana. Hacía bastante frío por la mañana y el sol salió durante el día, la computadora portátil se calentó mucho y entró en regulación térmica.



Él sabe que existe tal cosa, sabe que el entorno físico puede afectar el desempeño y rápidamente se dio cuenta de lo que estaba sucediendo. Tenía un modelo en la cabeza según el cual funciona el mundo, y en el marco de este modelo, más o menos rápidamente se dio cuenta de lo que estaba sucediendo.



Es decir, la habilidad más importante que se puede obtener en la evaluación comparativa es no saber todo en absolutamente todos los detalles: todos los tiempos de ejecución y todo el hardware. Lo principal es comprender cómo debe actuar para encontrar el problema, preferiblemente lo más rápido posible con el mínimo esfuerzo.



Daré una analogía con los idiomas. Cuando aprende su primer lenguaje de programación funcional, necesita modificar ligeramente su actitud hacia el mundo, para comprender los principios de la programación funcional, cómo debe pensar generalmente. Luego toma el siguiente lenguaje funcional X, y ya tiene estos principios en su cabeza. Ves un par de hola mundo y empiezas a escribir también.



Al mismo tiempo, es posible que no conozca algunos de los matices del idioma. Puede que no sepa cómo funcionan ciertas construcciones sintácticas, pero no le molesta tanto. Te sientes cómodo y escribes. Enfrentó un comportamiento incomprensible: lea el manual, lo descubrí, el nuevo hecho entró fácilmente en su imagen del mundo y fue más allá. Y nunca aprenderá todos los matices de todos los lenguajes funcionales del mundo, pero el enfoque general permanecerá en su cabeza.



Creo que necesitas alcanzar un nivel similar en cada área y luego ir en amplitud.



En algún momento de la evaluación comparativa, me centré específicamente en la precisión de la medición, en las características de ciertos tiempos de ejecución, un trozo de hierro, algo más. Entonces dejé de descubrir Estados Unidos por mí mismo cada vez, y todos los problemas de rendimiento comenzaron a caer en las clases que ya conocía. Y fui en amplitud, en la dirección del análisis de desempeño: qué hacer con los números que medimos. Y esta es el área en la que aún no he llegado al borde del conocimiento. Algunas cosas ya me han quedado claras, pero todavía hay un gran trabajo por delante: entender cómo aplicar todo esto en la práctica, qué fórmulas usar, cuáles no usar, qué enfoques son buenos y cuáles no.



La evaluación comparativa por el bien de la evaluación comparativa no es lo mejor que se puede hacer



Siempre debe haber algunos requisitos de desempeño comercial, siempre debe comprender por qué se está esforzando. Si no tiene requisitos comerciales, tampoco tiene sentido hacer desempeño. En consecuencia, cuando existen requisitos comerciales, ya comienza a comprender qué enfoques, al menos a simple vista, puede usar y cuáles no. Si no es así, vaya, evalúe, verifique qué enfoques se ajustan a sus requisitos.



Y cuando tiene un conjunto de algoritmos, opciones para escribir código, diseño y otras cosas, y todo se ajusta a los requisitos, ya elige lo que será más consistente con el resto del proyecto, lo que refleja sus puntos de vista sobre la estética, sobre cómo escribir código correctamente. ...



En términos generales, si tengo un máximo de 10 elementos en una colección y hay dos opciones: escribir un algoritmo simple para un cubo o uno muy complejo para n * log n, escribiré uno simple para un cubo que será claro para todos, que será fácil de mantener y modificar. Porque entiendo que nunca superará mis limitaciones de rendimiento.



Si escribió una solución lenta para un conjunto de datos pequeño y luego la usó para un conjunto de datos grande, y no tuvo consecuencias muy malas (generalmente ninguna), bueno, vamos a arreglarlo. Pero en la cabeza habrá un modelo de cómo evitar estos errores en el futuro.



Por ejemplo, puede poner aserrar al principio del método para que el número de elementos de la colección no supere tal o cual número. Entonces, el próximo programador que intente usar su método accidentalmente verá inmediatamente una excepción y no lo usará. Tales cosas vienen con la experiencia.



Hay otro problema: los requisitos comerciales volátiles. Definitivamente cambiarán, este es un axioma de nuestra realidad, no hay forma de escapar de esto. Con experiencia, podrá predecir a simple vista dónde pueden cambiar los requisitos, dónde vale la pena establecer un buen nivel de rendimiento, dónde puede aumentar la carga.



Si bien esta intuición no existe, puede pasar por prueba y error y ver qué sucede.



Siempre tienes una compensación entre rendimiento y belleza



Si escribe de la manera más eficiente posible, lo más probable es que su código sea simplemente terrible, repugnante, e incluso si cierra los ojos a la estética, será difícil de mantener, aparecerán errores sutiles constantemente en él, porque la arquitectura es mala, el código es malo, todo es malo.



Creo que debe concentrarse en los requisitos comerciales actuales y escribir el código más limpio, comprensible, hermoso y fácil de mantener dentro de ellos. Y en el momento en que comienza a cosechar (o existe la sensación de que pronto comenzará), entonces algo ya está cambiando.



E incluso si siempre se concentra únicamente en el rendimiento, no existe un código perfectamente optimizado y de máxima productividad. Significa todo: se olvidaron de C #, se olvidaron de todos los lenguajes hermosos. Y es mejor escribir en general en códigos de máquina, porque el ensamblador también tiene una sintaxis limitada. Y si escribe inmediatamente en los bytes, obtendrá un aumento de rendimiento.



En algunos casos, el código más rápido resulta ser el más hermoso, el más obvio, el más correcto. Pero tales compensaciones surgen inevitablemente en docenas y cientos de pequeños momentos. Digamos que existe algo como verificar si se exceden los límites de la matriz. Puede aceptar que el tiempo de ejecución se encargará de verificar el fuera de los límites de la matriz en todos los lugares, y si pasa al primer elemento menos, obtendrá una excepción y no leerá desde el fragmento de memoria izquierdo.



Y por esta confianza de que definitivamente nunca restas de la memoria incorrecta, pagas con una pequeña parte del rendimiento. Es decir, utilizamos el rendimiento como un recurso para que el programa sea más estable, comprensible y fácil de mantener.



El lenguaje no tiene la propiedad del rendimiento.



Si ve un artículo en el que X es más rápido que Y, puede cerrarlo. El lenguaje es una abstracción matemática. Este es un conjunto de reglas según las cuales se compila el programa. No tiene rendimiento, no tiene rendimiento, es algo que existe en tu cabeza y está plasmado en un editor de texto.



El rendimiento está disponible para tiempos de ejecución, entornos, programas específicos y apishe específicos. Cuando tiene en cuenta todos estos factores, puede hablar de rendimiento. Pero hay una explosión combinatoria, y no se puede decir que un código en este lenguaje sea siempre más rápido que otro código en este, porque están saliendo nuevas versiones de hardware y tiempos de ejecución. Nunca pasará por todas las combinaciones posibles de factores externos en su vida. Las apishkas que usa son fundamentalmente diferentes.



Por ejemplo, en un lenguaje condicional en las primeras etapas de desarrollo, implementaron un método para clasificar con una burbuja. Bueno, no lo sé, los chicos querían lanzar el lanzamiento lo antes posible, escribieron la clasificación más simple que pudieron hacer. Lo tomó, usó este método y resultó ser más lento en big data que en otro idioma donde se realiza la ordenación rápida. ¿Significa esto que se puede hablar sobre el desempeño de algunos idiomas? No. Se puede decir que este apish en particular de este idioma en este sistema operativo, en este hardware, en estos entornos, funciona más lento que otro apish de otro idioma en otro entorno. Entonces puedes decir. Pero resultará ser un párrafo de texto muy largo para formular correctamente.



Convencionalmente, podemos decir que C ++ es más rápido en la mayoría de los casos que JavaScript. Pero sería más correcto decir que los programadores de C ++ con buena experiencia en C ++ que escriben en C ++ escribirán un programa que probablemente sea más rápido que un javascriptor de JavaScript escribirán algo que funcionará en un navegador.



Pero también hay muchas reservas aquí. Pero, ¿qué pasa si el tipo que escribió en JavaScript dice que no es así y va a algún tipo de WebAssembly o algo más para rehacer? O busque en GitHub un superinterpretador / compilador de JavaScript que funcione con un subconjunto muy truncado de JS por tres construcciones de sintaxis y media, pero que produzca un código nativo súper rápido.



Y allí, si lo desea, puede escribir un código que superará a C ++. Además, puede escribir su propio compilador de JavaScript, que estará diseñado para compilar un solo programa y superar las "ventajas" en velocidad. Y esta es, en principio, una opción válida.



Presión social de un proyecto de código abierto popular



Con el crecimiento y la popularidad de los proyectos viene un cierto nivel de responsabilidad. Pero realmente no tienes obligaciones. Este hecho no siempre es fácil de entender, especialmente cuando todo tipo de personas vienen a GitHub y dicen: “¡No me funciona aquí! ¡Arréglalo urgentemente! Realmente necesito que esto funcione. ¡Ve y arréglalo! " O un tipo consigue un trabajo y yo estoy de vacaciones. Pasaron tres o cuatro días, ni siquiera vi que empezara algo ahí. Estoy descansando en algún lugar, y el tipo comienza: “¿Por qué diablos no me respondes? ¿Qué tipo de comunidad tiene este proyecto? Por lo general, todos ustedes son personas repugnantes, ¡tienen que hacer cosas malas con ustedes! Perdí mi tiempo, te escribí que te equivocaste, y no estás haciendo nada con eso, ¡me has estado ignorando durante cuatro días! Cómo es eso posible ?! "



Y cuanto más popular sea el proyecto, mayor será la presión social de las personas que creen que el código abierto es un lugar donde otras personas hacen su trabajo por usted de forma gratuita. Pero en realidad no lo es.



Y ahora, cuando aparece la inmunidad contra las personas que quieren algo de ti, la vida se vuelve mucho más fácil. Ahora llego a BenchmarkDorNet cuando tengo el tiempo y el estado de ánimo para codificar. Sé que hay muchos errores ahí. En su mayoría, no son críticos y se refieren a algunos casos marginales: en tal o cual entorno con la última vista previa de la quinta DotNet, algo en algún lugar no funciona. Bueno, está bien, que no funcione. Cuando esté de humor, iré a arreglarlo.



Si otras personas lo necesitan, pueden arreglarlo ellos mismos y enviar una solicitud de extracción; haré una revisión cuando tenga tiempo y estado de ánimo.






Mira el podcast completo aquí .



All Articles