¿Cuándo 'código de optimización' == 'estructuración de datos'?

9

Un artículo reciente de ycombinator enumera un comentario con los principios de un gran programador.

#7. Buen programador: optimizo el código. Mejor programador: estructurar datos. Mejor programador: ¿cuál es la diferencia?

Reconociendo conceptos subjetivos y contenciosos: ¿alguien tiene una posición sobre lo que esto significa? Lo hago, pero me gustaría editar esta pregunta más tarde con mis pensamientos para no predisponer las respuestas.

Nueva Alejandría
fuente
2
La lista a la que hace referencia tiene un montón de artículos geniales. Gracias.
DesarrolladorDon
Esta pregunta (que pregunté) tiene una respuesta que también menciona esta cita: programmers.stackexchange.com/q/168013/15028
TCSGrad

Respuestas:

16

Nueve de cada diez veces, cuando estructura bien su código / modelos, la optimización será obvia. ¿Cuántas veces has visto un nido de avispas y lo has encontrado totalmente subóptimo, donde al reestructurarlo, muchas redundancias se volvieron extremadamente obvias.

Un diseñador sabe que ha logrado la perfección no cuando no queda nada más que agregar, sino cuando no hay nada más que quitar. - Antoine de Saint-Exupéry

Un sistema bien estructurado será de naturaleza mínima y, debido a su naturaleza mínima, se optimizará porque lo poco que tiene se relaciona directamente con lo poco que hace para lograr su objetivo.

Editar: Para exponer sobre el punto que otros han eliminado de esto, también es completamente preciso ver que la declaración identifica la relación entre el código y los datos. Esa relación es así: si cambia la estructura de sus datos, deberá cambiar su código para respetar la estructura alterada. Si desea optimizar su código, es probable que necesite cambiar la estructura de sus datos para que su código sea capaz de manejar los datos de manera más óptima.

Dicho esto, hay una posibilidad totalmente separada que se estaba eludiendo aquí, y sería que este sujeto que tiene relaciones con YCombinator se esté refiriendo a los datos del código AS en la tradición de homoiconicidad de LISP. Es una exageración suponer esto como el significado en mi mente, pero es YCombinator, así que no descartaría que la cita simplemente diga que los LISPers son los "Mejores Programadores".

Jimmy Hoffa
fuente
1
Esto no habla de "datos" y de cómo "no hay diferencia entre optimizar el código y estructurar los datos". La optimización de código no malos datos reestructurar a menos que esto es una especie de auto-digestión, Turing completo, máquina
Nueva Alejandría
1
@NewAlexandria el modelo mencionado son los "datos". A menudo, el mal código y un mal modelo van de la mano. Arreglar uno implica arreglar el otro.
1
@NewAlexandria Me refiero a estructurar sus modelos como "datos" estructurantes, mi punto es simplemente que estructurar datos / código son sinónimos porque son parte del sistema como un todo e interdependientes. Estructurar bien también requerirá cambios en el otro, ¿es esto quizás más de lo que estaba buscando? Estaba tratando de explicar cómo la estructura y la optimización son las mismas, no cómo se relacionan el código y los datos, ¿tal vez entendí mal su pregunta si esa fue la parte confusa para usted?
Jimmy Hoffa
Creo que esto es lo más cercano a dilucidar el sentido correcto del tema. Ciertamente sabía cómo funciona esto, pero esperaba que alguien viera algo más profundo en la pregunta que cité.
Nueva Alejandría
4

Creo que el autor insinúa que cualquier reestructuración de los datos conduce a la reestructuración del código. Por lo tanto, la reestructuración de los datos con el objetivo de optimizar su sistema también lo obligará a optimizar su código, lo que provocará "¿cuál es la diferencia?" respuesta.

Tenga en cuenta que un "programador súper excelente" puede responder a "¿cuál es la diferencia?" que queda algo de diferencia allí: una vez que se aventura a optimizar el uso mejorado de la memoria caché de la CPU, puede mantener el diseño de sus estructuras de datos de la misma manera, pero cambiar el orden en el que accede a ellas puede hacer una gran cantidad de diferencia.

dasblinkenlight
fuente
Curiosamente, tenía la impresión de que el símil entre la estructura y la optimización era el tema de la declaración, no la relación entre el código y los datos, aunque tiene toda la razón sobre la relación y eso también lo explica. Se siente como separar un koan :)
Jimmy Hoffa
A veces, la reestructuración de datos permite la reestructuración del código, pero creo que a veces, cuando haya terminado, el nuevo código tiene muy poco en común con el código anterior.
DesarrolladorDon
OTOH, alinear datos para el tamaño de la línea de caché puede tener un gran impacto. ;-p
Macke
3

Considere el ejemplo más obvio de esto: "¡buscar datos de usuario es demasiado lento!"

Si sus datos de usuario no están indexados o al menos ordenados, entonces la reestructuración de sus datos producirá rápidamente un mayor rendimiento del código. Si los datos están estructurados correctamente y solo está iterando a través de la colección (en lugar de usar los índices o hacer algo como una búsqueda binaria), la modificación del código produce un mayor rendimiento del código.

Los programadores son solucionadores de problemas. Si bien es útil distinguir entre algoritmos y estructuras de datos, a menudo no pueden existir de forma aislada. Los mejores programadores lo saben y no se aíslan innecesariamente.

Telastyn
fuente
1

No estoy de acuerdo con la declaración mencionada anteriormente, bueno, al menos sin explicación. Veo que la codificación es la actividad que implica la utilización de algunas estructuras de datos. Las estructuras de datos generalmente influirían en la codificación. Entonces hay una diferencia entre los dos en mi opinión.

Creo que el autor debería haber escrito la última parte como "Mejor programador: optimizo ambos".

Hay un gran libro (al menos cuando estaba publicado) llamado: Algorithms + Data Structures = Programs .

Ninguna posibilidad
fuente
0

La optimización del código a veces puede mejorar la velocidad en un factor de dos, y ocasionalmente en un factor de diez o incluso veinte, pero eso es todo. Eso puede parecer mucho, y si un 75% del tiempo de ejecución de un programa se gasta en una rutina de cinco líneas cuya velocidad podría duplicarse fácilmente, tal optimización podría valer la pena. Por otro lado, la selección de estructuras de datos puede afectar la velocidad de ejecución en muchos órdenes de magnitud. Un procesador multiproceso hiper-optimizado moderno que ejecute código súper optimizado para buscar datos por clave en una lista enlazada lineal de 10,000,000 artículos almacenados en RAM sería más lento que un procesador mucho más lento que ejecuta una tabla hash anidada codificada de manera simple. De hecho, si uno tuviera los datos presentados correctamente, incluso un 1980 '

Dicho esto, el diseño de estructuras de datos eficientes a menudo requiere compensaciones más complejas que la optimización del código. Por ejemplo, en muchos casos, las estructuras de datos que permiten acceder a los datos de manera más eficiente son menos eficientes de actualizar (a veces por órdenes de magnitud) que aquellas que permiten actualizaciones rápidas, y aquellas que permiten las actualizaciones más rápidas pueden permitir el acceso más lento. Además, en muchos casos, las estructuras de datos que son óptimas para grandes conjuntos de datos pueden ser comparativamente ineficientes con las pequeñas. Un buen programador debe esforzarse por equilibrar esos factores competidores con la cantidad de tiempo de programador requerido para implementar y mantener diversas estructuras de datos, y ser capaz de lograr un equilibrio decente entre ellos.

Super gato
fuente
0

Las estructuras de datos manejan muchas cosas en relación con el rendimiento. Creo que podemos analizar los problemas de forma duradera con una idea preconcebida sobre la estructura de datos ideal y, en este contexto de pensamiento, incluso crear pruebas (a menudo por inducción) de la optimización. Por ejemplo, si ponemos una lista ordenada en una matriz y evaluamos cosas como el costo de insertar un elemento, podríamos decidir en promedio que necesitamos desplazar la mitad de la matriz para cada inserción. Para cada búsqueda binaria , podemos encontrar un elemento coincidente (o no) en log n pasos.

Alternativamente, si diferimos nuestra decisión sobre la estructura de datos (evitar la optimización prematura ) y estudiamos los datos que entran y el contexto en el que los usaremos, qué tan grande es, qué latencias ocurren y cuáles son importantes para los usuarios, cuánta memoria tenemos vs. usaría con representaciones de datos que conocemos o podemos idear.

En un área como ordenar y buscar, hay mucho que saber. Los programadores realmente buenos han estado trabajando en esto durante mucho tiempo. Comprender bien estos problemas es útil, y es una gran cosa si conoce más métodos que cuando terminó la clase de estructuras de datos de pregrado. Los árboles binarios pueden proporcionar un rendimiento superior para las inserciones a cambio de un mayor uso de memoria. Las tablas hash proporcionan mejoras aún mayores, pero aún más memoria. Un árbol de radix y una clasificación de radix pueden llevar mejoras aún más.

La estructuración creativa de los datos puede ayudar a replantear un problema y abrir la puerta a nuevos algoritmos que hacen que las aplicaciones difíciles sean más rápidas y, a veces, posibles tareas imposibles.

DesarrolladorDon
fuente
0

Para articular mi mejor conjetura sobre lo que significa el artículo, asumiré un subtexto tácito (que parece faltar en el artículo) que cualquier programador debe entender sobre la optimización:

  • La optimización se produce solo después de que el programa esté funcionando correctamente:
    • haz que funcione correctamente, luego hazlo correr rápido
    • Este principio es el punto de la máxima de Knuth, "la optimización prematura es la raíz de todo mal"
  • siempre y cuando haya determinado que la optimización no es prematura, primero debe medirla correctamente para determinar qué es lo que realmente necesita optimización, y una y otra vez durante la optimización, para saber qué efectos están teniendo sus intentos de optimización.
    • si su código se ejecuta en desarrollo, el generador de perfiles es su amigo en esto.
    • si su código se ejecuta en producción, debe instrumentar su código y, en su lugar, hacer amigos con su sistema de registro.

Ahora, entonces: sus mediciones le dirán en qué parte de su código la máquina está quemando la mayoría de los ciclos. Un "buen" programador se centrará en optimizar esas partes del código, en lugar de perder tiempo optimizando las partes irrelevantes.

Sin embargo, a menudo puede obtener mayores ganancias observando el sistema como un todo y encontrando alguna forma de permitir que la máquina haga menos trabajo. Con frecuencia, estos cambios requieren reelaborar la organización de sus datos; por lo tanto, un programador "mejor" se encontrará estructurando datos la mayoría de las veces.

El "mejor programador" tendrá un modelo mental completo de cómo funciona la máquina, una buena base en el diseño de algoritmos y una comprensión práctica de cómo interactúan. Esto le permite considerar el sistema como un todo integrado: no verá ninguna diferencia entre optimizar el código y los datos, porque los evalúa a nivel arquitectónico.

tormenta
fuente
-1

Mejor programador: ¿cuál es la diferencia?

Mejor programador? No, mal programador. Supongo que la palabra "optimización" significa aquellas cosas que los programadores suelen tratar de optimizar, memoria o tiempo de CPU. En este sentido, la optimización va en contra de la mayoría de las métricas de software. Comprensibilidad, mantenibilidad, comprobabilidad, etc.: todo esto toma poco tiempo cuando la optimización es el objetivo, a menos que lo que uno esté tratando de optimizar sea la comprensibilidad humana, la mantenibilidad, la comprobabilidad, etc. Sin mencionar el costo. Escribir un algoritmo óptimo de velocidad / espacio cuesta considerablemente más en términos de tiempo de desarrollador que codificar ingenuamente el algoritmo tal como se presenta en algún texto o revista. Un mal programador no sabe la diferencia. Una buena lo hace. El mejor programador sabe cómo determinar exactamente qué necesita ser optimizado y lo hace con criterio.

David Hammen
fuente