¿Cuándo es mejor optimizar un software para un mejor rendimiento, al principio o al final del desarrollo?

19

Soy un desarrollador de software junior y me preguntaba cuándo sería el mejor momento para optimizar un software para un mejor rendimiento (velocidad).

Suponiendo que el software no es extremadamente grande y complejo de administrar, ¿es mejor pasar más tiempo al principio optimizándolo o debería simplemente desarrollar el software que ejecuta todas las funciones correctamente y luego proceder a optimizarlo para un mejor rendimiento?

joepr
fuente
77
Experimento de pensamiento: eliges un lenguaje de programación interpretado para desarrollar tu juego interactivo y descubres a la mitad del proceso de desarrollo que el lenguaje que elegiste no posee la velocidad necesaria para cumplir con tu requisito de velocidad de cuadros. ¿Estás realmente jodido?
Robert Harvey
8
Otro experimento mental: optimizas cuidadosamente algún código en tu juego que crees que es crítico para el rendimiento, pero luego ejecutas un generador de perfiles en el código y descubres que el código que optimizaste en realidad no contribuye significativamente al rendimiento general, y has disminuyó la claridad del código. ¿Perdiste tu tiempo?
Robert Harvey
8
Corolario: ¿Es una decisión de uno u otro, o podría ser importante tomar algunas decisiones de desempeño desde el principio, mientras difiere otras?
Robert Harvey
1
Estaba escribiendo y eliminando una respuesta y seguí volviendo a escribirla. Simplemente no hay una respuesta a esta pregunta porque depende. En algunos casos, apresurar un producto supera todas las demás consideraciones, en otros casos, la optimización desde el principio es un requisito difícil y un millón de otros escenarios donde es válido o no optimizar, optimizar desde el principio o no optimizar en absoluto y cualquier otra cosa.
Pieter B
No importa cómo lo mires. Al principio no hay nada que optimizar, ya que no hay nada con lo que comparar. Todavía necesita 2 referencias para optimizar algo: el rendimiento ideal (de acuerdo con los requisitos) y el real (el que obtiene una vez que se ejecuta algo).
Laiv

Respuestas:

52

La cosa número uno debe ser siempre y para siempre legibilidad. Si es lento pero legible, puedo arreglarlo. Si está roto pero es legible, puedo arreglarlo. Si es ilegible, tengo que preguntarle a otra persona qué se supone que debe hacer.

Es notable cuán eficiente puede ser su código cuando solo estaba enfocado en ser legible. Tanto es así que generalmente ignoro el rendimiento hasta que tengo una razón para preocuparme. Eso no debe entenderse como que no me importa la velocidad. Hago. Acabo de descubrir que hay muy pocos problemas cuyas soluciones en realidad son más rápidas cuando son difíciles de leer.

Solo dos cosas me sacan de este modo:

  1. Cuando veo la posibilidad de una gran mejora de O , incluso cuando solo n es lo suficientemente grande como para que a alguien le importe.
  2. Cuando tengo pruebas que muestran problemas reales de rendimiento. Incluso con décadas de experiencia, sigo confiando en las pruebas más que en mis matemáticas. Y soy bueno en matemáticas.

En cualquier caso, evite la parálisis del análisis haciéndose creer que no debería probar una solución porque podría no ser la más rápida. Su código realmente se beneficiará si prueba con varias soluciones, ya que realizar los cambios lo obligará a usar un diseño que facilite el cambio. Una base de código flexible se puede hacer más rápido más tarde donde realmente lo necesita. Elija flexible sobre la velocidad y puede elegir la velocidad que necesita.

naranja confitada
fuente
Siempre he descubierto que lo principal en lo que los desarrolladores de software deben centrarse es en poner un producto en los estantes lo más rápido posible con una interfaz lo más bonita posible, los errores y el mal diseño se pueden solucionar más adelante.
Pieter B
12
@PieterB: es muy fácil ralentizar el desarrollo mediante una estrategia como "los errores y el mal diseño se pueden solucionar más adelante" . Tenga en cuenta que por mal diseño me refiero a cosas como códigos ilegibles y complicados, así como códigos de ingeniería excesiva.
Doc Brown
55
@Walfrat: Creo que su ejemplo puede acelerarse fácilmente sin sacrificar la legibilidad, y estoy interpretando esta respuesta no como "el código legible no tiene ningún problema de rendimiento", sino más bien como "los problemas de rendimiento no se evitarán automáticamente haciendo código ilegible".
Doc Brown
2
@PieterB: o tienes un cliente que quiere recuperar su dinero porque el producto que compraron tiene tantos errores que no pueden usarlo.
Doc Brown
2
@svidgen evaluar la velocidad del código ilegible sin pruebas es casi imposible. Centrarse en la velocidad e ignorar la legibilidad crea problemas de velocidad no diagnosticables. Centrarse en la legibilidad hace que los problemas de velocidad sean tan obvios que no tendrá que pensar en ello. Lo verás en el momento en que lo escribas. Incluso si no lo hace, una vez que lo pruebe al menos podrá encontrar el problema. Dado todo esto, ¿por qué alguien debería enfocarse por defecto en la velocidad sobre la legibilidad? Enfocarse en la velocidad e ignorar la legibilidad no te da ninguno.
candied_orange
27

Si es necesario un cierto nivel de rendimiento (un requisito no funcional), ese debería ser un objetivo de diseño desde el principio. Por ejemplo, esto puede influir en qué tecnologías podrían ser apropiadas o en cómo estructurar el flujo de datos en el programa.

Pero, en general, no es posible optimizar antes de escribir el código: primero haga que funcione, luego que sea correcto y, finalmente, que sea rápido .

Un gran problema con la optimización antes de implementar la mayoría de las funciones es que te has encerrado en decisiones de diseño subóptimas en los lugares equivocados. A menudo (pero no necesariamente) existe una compensación entre la mantenibilidad y el rendimiento. ¡La mayoría de las partes de su programa son totalmente irrelevantes para el rendimiento! Los programas típicos solo tienen algunos puntos calientes que realmente vale la pena optimizar. Por lo tanto, sacrificar la capacidad de mantenimiento por el rendimiento en todos aquellos lugares que no lo necesitan es un mal negocio.

La optimización para la mantenibilidad es el mejor enfoque. Si gasta su inteligencia en la mantenibilidad y los diseños claros, a la larga le resultará más fácil identificar secciones críticas y optimizarlas de manera segura sin comprometer el diseño general.

amon
fuente
15

cuándo sería el mejor momento para optimizar un software para un mejor rendimiento (velocidad).

Comience por eliminar de su mente el concepto de que el rendimiento es lo mismo que la velocidad. El rendimiento es lo que el usuario cree que es el rendimiento .

Si hace que una aplicación responda el doble de rápido a un clic del mouse y pasa de diez microsegundos a cinco microsegundos, al usuario no le importa. Si hace que una aplicación responda el doble de rápido a un clic del mouse y pasa de cuatro mil años a dos mil años, nuevamente, al usuario no le importa.

Si realiza su aplicación dos veces más rápido y usa toda la memoria en la máquina y se bloquea, al usuario no le importa que ahora sea el doble de rápido.

El rendimiento es la ciencia de hacer compensaciones efectivas sobre el consumo de recursos para lograr una experiencia de usuario particular. El tiempo del usuario es un recurso importante , pero nunca se trata solo de "más rápido". Alcanzar los objetivos de rendimiento casi siempre requiere compensaciones, y a menudo están intercambiando tiempo por espacio o viceversa.

Asumiendo que el software no es extremadamente grande y complejo de administrar

Esa es una suposición terrible.

Si el software no es grande y complejo de administrar, entonces probablemente no resuelva un problema interesante que le interese a un usuario, y probablemente sea muy fácil de optimizar.

¿Es mejor pasar más tiempo al principio optimizándolo o debería simplemente desarrollar el software que ejecuta todas las funciones correctamente y luego proceder a optimizarlo para un mejor rendimiento?

Estás sentado allí en una página en blanco y escribes void main() {}¿Comienzas a optimizar? ¡No hay nada que optimizar! El orden correcto es:

  • Hazlo compilar
  • Hazlo correcto
  • Hazlo elegante
  • Hazlo rápido

Si intenta hacerlo en cualquier otro orden, termina con un código incorrecto que es un desastre, y ahora tiene un programa que produce respuestas incorrectas muy rápidamente y se resiste a los cambios.

Pero hay un paso que falta allí. El verdadero orden correcto es:

  • Trabaje con los clientes y la administración para establecer objetivos y métricas de desempeño realistas y medibles, recordando que la velocidad no es la única métrica que les importa a los clientes.
  • Implemente un arnés de prueba que pueda rastrear el estado actual del proyecto contra sus objetivos
  • Hazlo compilar
  • Ejecute las pruebas. Si ya no está dentro de su objetivo, tenga en cuenta que es posible que haya recorrido un mal camino antes. Usa la ciencia . ¿Introdujo un algoritmo incorrecto que se puede arreglar o es algo fundamentalmente incorrecto? Si está fundamentalmente mal, entonces comience de nuevo. Si se puede solucionar, ingrese un error y vuelva a él más tarde.
  • Hazlo correcto
  • Ejecute las pruebas nuevamente ...
  • Hazlo elegante
  • Ejecute las pruebas nuevamente ...
  • ¿Cumple con su objetivo? Si es así, ve a la playa . Si no, hazlo lo suficientemente rápido .
Eric Lippert
fuente
"El rendimiento es lo que el usuario cree que es el rendimiento". - de hecho, en algún momento la experiencia del usuario es en realidad mejor cuando las cosas nos esperan a tomar tiempo hacen tomar tiempo: webdesignerdepot.com/2017/09/when-slower-ux-is-better-ux
svidgen
tal vez "ser científico" en lugar de "usar la ciencia" :)
azul
@svidgen: Recuerdo una vez que cambié mi código para reducir la velocidad de una barra de progreso. Los usuarios tuvieron la impresión de que se estaba haciendo un trabajo real y estaban contentos con eso. La función que se estaba calculando era útil, pero parecía que el programa no estaba haciendo nada si el resultado estaba allí después de una décima de segundo.
Giorgio
2
@Giorgio: Esto me data, pero recuerdo cuando obtuve un disco duro por primera vez, y guardaba un juego o un documento y pensaba que algo había salido mal porque la operación no tomó un tiempo perceptible en comparación con guardar en un disquete. Y, por supuesto, ahora el estado del juego y los documentos son tan grandes que volvemos a ahorrar tiempo.
Eric Lippert
3

Como regla general, lo mejor es optimizar el rendimiento más adelante, pero he visto que muchos proyectos salen mal cuando los desarrolladores se dan cuenta de que terminaron con un software que se ralentiza cuando se le agrega una carga o datos significativos.

Por lo tanto, un enfoque intermedio sería lo mejor en mi opinión; no le pongas demasiado énfasis, pero no ignores el rendimiento por completo.

Daré un ejemplo que he visto muchas veces; dada una biblioteca ORM, tenemos una entidad de usuario que puede tener uno o más pedidos. Realicemos un bucle de todos los pedidos para un usuario y descubramos cuánto ha gastado el usuario en nuestra tienda, un enfoque ingenuo:

User user = getUser();
int totalAmount;
for (Order o : user.getOrders()) {
  totalAmount += o.getTotalAmount();
} 

He visto a desarrolladores escribir cosas similares, sin pensar en las implicaciones; primero obtenemos al usuario, que con suerte solo será una consulta SQL en la tabla de usuarios (pero podría implicar mucho, mucho más), luego recorremos los pedidos, lo que podría incluir obtener todos los datos relevantes para todas las líneas de pedido en el pedido , información del producto, etc., ¡todo esto para obtener un número entero para cada pedido!

La cantidad de consultas SQL aquí puede sorprenderlo. Por supuesto, depende de cómo estén estructuradas sus entidades.

Aquí, el enfoque correcto probablemente sería agregar una función separada para obtener la suma de la base de datos a través de una consulta separada escrita en el lenguaje de consulta proporcionado por el ORM, y recomendaría hacer esto la primera vez , y no posponer esto Para luego; porque si lo hace, probablemente terminará con muchos más problemas que resolver y no estará seguro de por dónde empezar.

Vetle
fuente
3

El rendimiento total del sistema es producto de las complejas interacciones de la totalidad de los componentes del sistema. Es un sistema no lineal. Por lo tanto, el rendimiento estará determinado no solo por el rendimiento individual de los componentes sino por los cuellos de botella entre ellos.

Obviamente, no puede probar los cuellos de botella si todavía no se han creado todos los componentes de su sistema, por lo que no puede probar muy bien desde el principio. Por otro lado, después de construir el sistema, es posible que no le resulte tan fácil realizar los cambios que necesita para obtener el rendimiento que desea. Así que este es un hueso de buena Catch-22 .

Para hacer las cosas más difíciles, su perfil de rendimiento puede cambiar drásticamente cuando cambia a un entorno similar a la producción, que a menudo no está disponible desde el principio.

Entonces, ¿Qué haces? Bueno, algunas cosas.

  1. Se pragmático. Al principio, puede optar por utilizar las características de la plataforma que son "mejores prácticas" para el rendimiento; por ejemplo, utilice la agrupación de conexiones, las transacciones asincrónicas y evite la capacidad de estado, que puede ser la muerte de una aplicación multiproceso donde diferentes trabajadores compiten por el acceso a datos compartidos. Normalmente no probarías estos patrones para el rendimiento, solo sabrías por experiencia lo que funciona bien.

  2. Se iterativo. Tome medidas de rendimiento de referencia cuando el sistema sea relativamente nuevo y vuelva a probar ocasionalmente para asegurarse de que el código recién introducido no haya degradado demasiado el rendimiento.

  3. No optimices demasiado temprano. Nunca se sabe lo que va a ser importante y lo que no va a importar; un algoritmo de análisis de cadenas superrápido puede no ayudar si su programa está constantemente esperando E / S, por ejemplo.

  4. Especialmente en las aplicaciones web, puede centrarse no tanto en el rendimiento sino en la escalabilidad. Si la aplicación puede escalar, el rendimiento casi no importa, ya que puede seguir agregando nodos a su granja hasta que sea lo suficientemente rápido.

  5. Se presta especial atención a la base de datos. Debido a las restricciones de integridad transaccional, la base de datos tiende a ser un cuello de botella que domina cada parte del sistema. Si necesita un sistema de alto rendimiento, asegúrese de tener personas con talento trabajando en el lado de la base de datos, revisando los planes de consulta y desarrollando estructuras de tablas e índices que harán que las operaciones comunes sean lo más eficientes posible.

La mayoría de estas actividades no son para el comienzo o el final del proyecto, sino que deben ser atendidas continuamente .

John Wu
fuente
1

Soy un desarrollador de software junior y me preguntaba cuándo sería el mejor momento para optimizar un software para un mejor rendimiento (velocidad).

Comprende que hay 2 extremos muy diferentes.

El primer extremo son las cosas que afectan una gran parte del diseño, como cómo dividir el trabajo en cuántos procesos y / o subprocesos y cómo se comunican las piezas (sockets TCP / IP? Llamadas de función directa?), Ya sea para implementar un JIT avanzado o un intérprete de "un código de operación a la vez", o si planear estructuras de datos para que sean susceptibles a SIMD, o ... Estas cosas tienden a tener una fuerte influencia en la implementación y se vuelven excesivamente difíciles / costosas de adaptar.

El otro extremo son las micro optimizaciones, pequeños ajustes por todas partes. Estas cosas tienden a no tener casi influencia en la implementación (y a menudo son mejor hechas por un compilador de todos modos), y es trivial hacer estas optimizaciones siempre que lo desee.

Entre estos extremos hay una gran área gris.

A lo que realmente se reduce es a la experiencia / suposiciones educadas que se utilizan para responder una pregunta de "¿los beneficios justifican los costos"? Para optimizaciones en / cerca de un extremo si adivina mal a menudo, significa deshacerse de todo su trabajo y reiniciar desde cero o fallar en el proyecto (demasiado tiempo dedicado a un diseño innecesariamente demasiado complicado). En / cerca del otro extremo, es mucho más sensato dejarlo hasta que pueda probar que es importante utilizando la medición (por ejemplo, el perfil).

Desafortunadamente, vivimos en un mundo donde demasiadas personas piensan que la optimización solo incluye las cosas (en su mayoría irrelevantes) en el extremo "trivial".

Brendan
fuente
1

Es más fácil escribir código que no sea porformante ni mantenible. Es más difícil escribir código porformante. Todavía es más difícil escribir código mantenible. Y es el código más difícil de escribir que se puede mantener y realizar.

Pero es más fácil hacer que el código se pueda mantener, que hacer que el código se pueda mantener.

Ahora, obviamente, depende del tipo de sistema que esté haciendo, algunos sistemas serán muy críticos para el rendimiento y necesitarán eso planeado desde el principio. Para las personas extremadamente talentosas como Eric Lippert, que respondieron anteriormente, estos sistemas pueden ser comunes; pero para la mayoría de nosotros, son la minoría de los sistemas que construimos.

Sin embargo, dado el estado del hardware moderno, en la mayoría de los sistemas, no es necesario prestar especial atención a la optimización desde el principio, sino que evitar la destrucción del rendimiento suele ser suficiente. Lo que quiero decir con esto es que evite hacer cosas simplemente estúpidas, como recuperar todos los registros de una tabla para obtener un recuento en lugar de solo consultar select count(*) from table. Simplemente evite cometer errores y haga un esfuerzo por comprender las herramientas que está utilizando.

Luego, primero enfóquese en hacer que su código sea mantenible. Con esto quiero decir:

  1. Separe las preocupaciones de la forma más estricta posible (por ejemplo, no mezcle el acceso a datos con la lógica empresarial)
  2. Tipos de resúmenes de referencia en lugar de tipos concretos cuando sea posible
  3. Haga que su código sea comprobable

El código que se puede mantener es mucho más fácil de optimizar cuando las estadísticas muestran que es necesario.

Luego, asegúrese de que su código tenga MUCHAS pruebas automáticas, esto tiene varios beneficios. Menos errores significa más tiempo para optimizar, cuando sea necesario . Además, cuando optimiza, puede iterar y encontrar la mejor solución mucho más rápido ya que encuentra errores en sus implementaciones mucho más rápido.

Los scripts de implementación automatizados y la infraestructura de scripts también son muy útiles para el ajuste del rendimiento, ya que, nuevamente, le permiten iterar más rápido; sin mencionar sus otros beneficios.

Entonces, como siempre, hay excepciones (que necesitará experiencia para identificarlo mejor), pero, en general, mi consejo es: Primero, aprenda sus herramientas y evite codificar cuellos de botella en el rendimiento. Segundo, asegúrese de que su código sea mantenible. Tercero, pruebas automatizadas. Cuarto, implementaciones totalmente automatizadas. Solo después de hacer estas cosas, debe preocuparse por la optimización.

TheCatWhisperer
fuente
1

Podría estar sesgado al trabajar en áreas muy críticas para el rendimiento, como el procesamiento de imágenes y el trazado de rayos, pero aún así diría que optimice "lo más tarde posible" . No importa cuán críticos sean sus requisitos de rendimiento, siempre hay mucha más información y claridad en retrospectiva, después de medir, que por adelantado, lo que significa que incluso las optimizaciones más efectivas se aplican más tarde después de obtener dicho conocimiento.

Casos peculiares

Pero a veces "lo más tarde posible" todavía es bastante temprano en algunos casos peculiares. Si hablamos de procesadores sin conexión, por ejemplo, las estructuras de datos y las técnicas que utiliza para lograr el rendimiento realmente se filtran en el diseño del usuario final. Esto puede sonar repugnante, pero el campo es tan avanzado y tan crítico para el rendimiento que los usuarios aceptan los controles del usuario final específicos de las técnicas de optimización aplicables a un rastreador de rayos en particular (por ejemplo, almacenamiento en caché de irradiancia o mapeo de fotones), ya que algunos de ellos se utilizan a las horas de espera para que se renderice una imagen, y otros están acostumbrados a repartir enormes sumas de dinero para alquilar o poseer una granja de renderizado con máquinas dedicadas al renderizado. Hay una reducción masiva en tiempo y dinero para esos usuarios si un renderizador fuera de línea competitivo puede ofrecer una reducción no trivial en el tiempo dedicado a la representación. Este es un tipo de área donde una reducción del 5% en el tiempo realmente emociona a los usuarios.

En casos tan peculiares, no puede simplemente elegir una técnica de renderizado de manera involuntaria y esperar optimizarla más adelante, ya que todo el diseño, incluido el diseño del usuario final, gira en torno a las estructuras de datos y los algoritmos que utiliza. No necesariamente puede simplemente ir con lo que funcionó bien para otras personas, ya que aquí, usted, como individuo, y sus fortalezas y debilidades particulares, tienen un gran factor para ofrecer una solución competitiva. La mentalidad y la sensibilidad del desarrollador principal detrás de Arnold son diferentes de las que trabajan en VRay que usaron un enfoque muy diferente; no necesariamente pueden intercambiar lugares / técnicas y hacer el mejor trabajo (a pesar de que ambos son líderes industriales). Tienes que experimentar y crear prototipos y puntos de referencia y encontrar lo que ' eres particularmente bueno en hacerlo dada la infinita variedad de técnicas de vanguardia que existen si esperas enviar algo competitivo que realmente se venda. Entonces, en este caso peculiar, las inquietudes de rendimiento se mueven hacia adelante como tal vez la preocupación más importante incluso antes de comenzar el desarrollo.

Aún así, eso no es necesariamente una violación de la optimización "lo más tarde posible" , es simplemente "lo más tarde posible" es bastante temprano en estos casos extremos y peculiares. Averiguar cuándo y qué no necesita problemas de rendimiento tan tempranos, si acaso, es probablemente el principal desafío para el desarrollador. Lo que no se debe optimizar podría ser una de las cosas más valiosas para aprender y seguir aprendiendo en la carrera de un desarrollador, ya que no puede encontrar escasez de desarrolladores ingenuos que quieran optimizar todo (y desafortunadamente incluso algunos veteranos que lograron mantener su trabajo de alguna manera a pesar de su contraproductividad).

Lo más tarde posible

Quizás la parte más difícil es tratar de entender lo que significa. Todavía estoy aprendiendo y he estado programando durante casi tres décadas. Pero especialmente ahora en mi tercera década, estoy empezando a darme cuenta de que no es tan difícil. No es ciencia espacial, si te enfocas más en el diseño que en la implementación. Mientras más diseños dejen espacio para respirar para optimizaciones apropiadas más tarde sin cambios en el diseño, más tarde podrá optimizar. Y cada vez más productividad he ganado buscando tales diseños que me brinden ese espacio para respirar.

Diseñe qué ofrece sala de respiración para optimizar más tarde

Estos tipos de diseños en realidad no son tan difíciles de lograr en la mayoría de los casos si podemos aplicar algo de "sentido común". Como historia personal, me interesan las artes visuales como pasatiempo (creo que es de alguna manera útil programar software para que los artistas sean algo como yo mismo para comprender sus necesidades y hablar su idioma), y pasé un tiempo a principios de la década de 2000 usando los applets de Oekaki en línea como una forma rápida de garabatear y compartir mi trabajo y conectarme con otros artistas.

En particular, mi sitio y applet favoritos estaban plagados de fallas de rendimiento (cualquier tamaño de pincel no trivial se ralentizaría), pero tenía una comunidad muy agradable. Para solucionar los problemas de rendimiento, utilicé pequeños pinceles de 1 o 2 píxeles y garabateé mi trabajo así:

ingrese la descripción de la imagen aquí

Mientras tanto, seguía dando al autor de las sugerencias de software para mejorar el rendimiento, y se dio cuenta de que mis sugerencias eran de naturaleza particularmente técnica hablando de optimizaciones de memoria y algoritmos, etc. Entonces él realmente preguntó si yo era programador y yo dije que sí y me invitó a trabajar en el código fuente.

Así que miré el código fuente, lo ejecuté, lo perfilé, y para mi horror, él había diseñado el software en torno al concepto de una "interfaz de píxeles abstractos" IPixel, que terminó siendo la causa raíz detrás de los principales puntos críticos para todo lo dinámico. asignaciones y despacho para cada píxel de cada imagen. Sin embargo, no había una forma práctica de optimizar eso sin reconsiderar el diseño de todo el software porque el diseño lo había atrapado en una esquina donde no hay mucho más allá de las micro optimizaciones más triviales cuando nuestras abstracciones funcionan al nivel granular de un solo píxel abstracto. y todo depende de este píxel abstracto.

Creo que es una violación del "sentido común", pero obviamente no fue un sentido común para el desarrollador. Pero es como no abstraer las cosas a un nivel tan granular donde incluso los casos de uso más básicos serán instanciados por millones, como con píxeles, partículas o pequeñas unidades en una simulación de ejército descomunal. Favorezca el IImage(puede manejar todos los formatos de imagen / píxel que necesita en ese nivel agregado más voluminoso) o IParticleSystemhacia IPixelo IParticle, y luego puede colocar las implementaciones más básicas y rápidas de escribir y fáciles de entender detrás de tales interfaces y tenga todo el espacio de respiración que necesitará para optimizar más adelante sin tener que reconsiderar todo el diseño del software.

Y ese es el objetivo tal como lo veo en estos días. Excluyendo los casos peculiares como los renderizadores sin conexión anteriores, diseñe con suficiente espacio para respirar para optimizar lo más tarde posible, con tanta información retrospectiva como sea posible (incluidas las mediciones), y aplique las optimizaciones necesarias lo más tarde posible.

Por supuesto, no estoy sugiriendo necesariamente comenzar usando algoritmos de complejidad cuadrática en entradas que alcanzan fácilmente un tamaño no trivial en casos comunes de usuarios finales. ¿Quién hace eso de todos modos? Pero ni siquiera creo que sea un gran problema si la implementación es fácil de cambiar más tarde. Eso todavía no es un grave error si no tiene que reconsiderar ningún diseño.

Dragon Energy
fuente
0

Depende de lo que ese rendimiento signifique para su aplicación. Y sobre si es posible optimizar el rendimiento antes de que su aplicación esté funcionalmente completa.

En la mayoría de los casos, no debe preocuparse por ello hasta que no tenga nada mejor que hacer, pero podría ser que un cierto nivel de rendimiento sea crítico para el éxito de su aplicación. Si ese fuera el caso y sospechas que puede no ser fácil, deberías comenzar a ver el rendimiento por el simple "fracaso rápido".

Un principio importante para cualquier proyecto es enfocarse primero en las partes duras. De esa manera, si resulta que no puede hacerlo, lo sabrá temprano y habrá tiempo para intentar algo totalmente diferente o el proyecto puede cancelarse antes de que se gaste demasiado en él.

Martin Maat
fuente
0

Voy a sugerir que el rendimiento es más que la velocidad. Incluye escala (cientos a miles de usuarios concurrentes). Por supuesto, no desea que la aplicación se acumule cuando reciba una carga de producción. El rendimiento incluye la cantidad de recursos (por ejemplo, memoria) que consume la aplicación.

El rendimiento también es facilidad de uso. Algunos usuarios prefieren que 1 pulsación de tecla haga una tarea en 10 segundos que 2 pulsaciones de tecla que realicen la tarea en 1 segundo. Para cosas como esa, pregunte a su líder de diseño. No me gusta llevar cosas como esta a los usuarios antes. En el vacío pueden decir X pero una vez que están trabajando con un prelanzamiento funcional pueden decir Y.

La mejor velocidad individual es mantener un recurso como una conexión de base de datos. Pero para la escala, debe adquirir la conexión lo más tarde posible y liberarla lo antes posible. Un viaje a la base de datos para obtener 3 cosas es más rápido que 3 viajes separados a la base de datos.

¿Está haciendo viajes para obtener información que no cambia durante la sesión? Si es así, consígalo al inicio de la sesión y manténgalo en la memoria.

Al elegir el tipo de colección, tenga en cuenta el funcional, la velocidad y el tamaño.

¿Estás seguro de que necesitas guardar los artículos en una colección? Un problema común es leer todas las líneas de un archivo en una lista y luego procesar la lista línea por línea. Es mucho más eficiente leer el archivo línea por línea y omitir la lista.

¿Está haciendo un bucle tres veces cuando podría hacerlo una vez y hacer tres cosas?

¿Hay algún lugar en el que deba procesar en otro hilo con una devolución de llamada? Si es así, empaquete el código con esa posible necesidad en mente si no interfiere con las necesidades de diseño inmediatas.

Una gran cantidad de rendimiento también es código limpio.

Hay una optimización prematura y solo hay cosas de sentido común por adelantado que realmente no toman más tiempo.

En la base de datos es donde veo la optimización prematura. Se normalizará la velocidad antes de que haya un problema de velocidad. El argumento que obtengo es que si cambiamos la tabla más tarde, entonces tenemos que cambiar todo. A menudo, puede crear una vista que presente los datos de esa manera y es posible que deba cambiarse por una tabla desnormalizada más adelante.

paparazzo
fuente