¿Cómo se llama cuando se cambia el tiempo de ejecución de Big O de una función [cerrado]

19

Digamos que tengo una función que ordena una base de datos a O(n^2)tiempo. Quiero continuar refactorizándolo para que se ejecute a O(n log(n))tiempo, y al hacerlo, cambiaré la forma fundamental en que se ejecuta la operación, manteniendo los valores de retorno y las entradas equivalentes.

¿Cómo llamo a esta actividad de refactorización?

"Acelerar" no parece correcto, ya que puede hacer que un algoritmo vaya más rápido sin cambiar la gran velocidad de O a la que se ejecutó.

"Simplificar" tampoco parece correcto.

¿Cómo llamo a esta actividad?

Actualizar

La mejor respuesta que pude encontrar es reducir la complejidad temporal asintótica.

Code Whisperer
fuente
¿Se espera que los algoritmos sean más rápidos en la mayoría de los casos de uso después de la modificación? Para tenerlo en cuenta, a veces es bueno pasar a una clase de complejidad de mejor escala incluso con un impacto de rendimiento promedio esperado, solo para obtener un comportamiento de rendimiento más consistente.
Nat
22
Esto no es refactorizar
theonlygusti
66
Estrictamente hablando, la función que se ejecuta en el O(log(n))tiempo también se ejecuta en el O(n^2)tiempo. El significado de O(n^2)es "no crece más rápido que el cuadrático". Probablemente quisiste decir Theta (log (n)) que significa "crece tan rápido como log(n)". en.wikipedia.org/wiki/…
Džuris
44
<pedante> no ha cambiado el tiempo de ejecución grande de una función. una función es una relación entre un dominio y un codominio y existe independientemente de sus pequeños intentos humanos de implementación. en su lugar, encontró un algoritmo de mejor rendimiento que implementa la función </pedantic> <human> buen trabajo </human>
emory
55
@theonlygusti: Depende. Si la función anteriormente hizo una garantía / garantías sobre complejidades, no es refactorización. Si no garantiza nada, está refactorizando. Si incluso fue explícito acerca de no hacer garantías, es especialmente una refactorización.
phresnel

Respuestas:

44

Normalmente se llama "optimización del rendimiento" , pero no lo llamaría "refactorización", ya que este término generalmente se refiere a cambios en el código que no cambian su comportamiento visible . Y un cambio en Big-O es definitivamente algo que yo llamaría un cambio visible.

al hacerlo, cambiaré la forma fundamental en que se ejecuta la operación

En este caso, su optimización es una reescritura de esa función. No todas las optimizaciones, incluso si cambian "Big-O", son necesariamente una reescritura, a veces solo son necesarios pequeños cambios para lograr tal mejora, pero aun así, soy reacio a usar el término "refactorización" para esto, porque tiende a dar una impresión errónea sobre la naturaleza del cambio.

EDITAR: Revisé la lista de refactorización de Fowler , y entre estas ~ 100 refactorizaciones con nombre, la última se llama "Algoritmo sustituto" . Entonces, si tomamos esto como referencia canónica, hay una pequeña área gris donde una optimización de la forma descrita podría llamarse un tipo especial de refactorización (pero en mi humilde opinión, no es una típica). Tenga en cuenta también que el objetivo de Fowler con todas las refactorizaciones siempre fue mejorar el diseño con enfoque en la capacidad de mantenimiento y la capacidad de evolución del código existente sin reescribirlo, y claramente no la optimización del rendimiento.

Doc Brown
fuente
10
¿De Verdad? Creo que la refactorización es correcta a menos que los requisitos cambien. Entonces ... No, si la función se llama BubbleSort, pero sí, si es solo Sort
Ewan
3
@Ewan Sí, legalmente una refactorización puede ser una optimización del rendimiento, pero la primera es demasiado general y no capta adecuadamente el impacto de los cambios.
Deduplicador
1
Estuve en una presentación temprana del tipo que inventó y acuñó Refactoring (Fowler?) Y toda la idea estaba relacionada con la programación automática y las mejoras comprobables comprobables del código que no tenían efecto en la entrada frente a la salida.
Sentinel
1
@Steve. Convenido. Simplemente estaba agregando al consenso que las mejoras de Big O representan una mejora algorítmica, no mejoras en cómo se representan o mantienen esos algoritmos. En otras palabras, la actividad es una reescritura
Sentinel
1
@ Steve: sí, lo sabía, pensé en agregar una nota a mi respuesta. Mi edición fue solo una nota para aclarar que hay una pequeña área gris.
Doc Brown
13

No creo que haya un término estándar, un uso común es optimizar aunque mejorar , o acelerar también sería correcto al hacer la aclaración de que está hablando de cambios de código y no de hardware.

ichantz
fuente
7

Como otros han dicho, "optimizar" es el término general para mejorar el rendimiento de un algoritmo. Sin embargo, optimizar a menudo significa mejorar factores constantes. Si quisiera decir de manera concisa pero clara que he reducido la complejidad asintótica (del tiempo), diría que he "mejorado el rendimiento asintótico". A veces la gente describirá esto como "mejorar la escala" pero esto es especialmente ambiguo hoy en día.

Advertencia : Reducir la complejidad del tiempo asintótico no es necesariamente lo mismo que optimizar en un contexto práctico . A menudo se utilizan algoritmos asintóticamente no óptimos porque en el rango de entradas el programa en realidad está expuesto a los algoritmos menos óptimos que funcionan mejor.

Derek Elkins dejó SE
fuente
5

Será dependiente del contexto.

"Reparar un error de rendimiento de tiempo de ejecución cuadrático" es típicamente lo que veo. Sin embargo, si eso merece arreglarse (un cambio de código) depende del contexto.

Tenga en cuenta que las bases de datos proporcionan muchas herramientas para mejorar la complejidad del tiempo. Por ejemplo, para obtener los mejores resultados de N de una base de datos, solo dígalo. Al convertir kludge ineficiente en llamada optimizada incorporada, la explicación parece superflua.

La razón por la que considero un algoritmo con tiempo de ejecución cuadrático para merecer una revisión de código (discusión) no es tanto porque es lento (lento es relativo; cuadrático es rápido en comparación con exponencial), sino porque la intuición humana (como sus clientes, o compañeros programadores) se sienten incómodos por naturaleza con una funcionalidad de software que se desvía demasiado del tiempo de ejecución lineal, debido a la mezcla de expectativas de la vida cotidiana.

Muchas de las quejas de los clientes sobre el rendimiento del software se dividen en estas dos categorías:

  • Todo el sistema (software y hardware) se especificó en función del uso estimado. La semana pasada, todo funciona bien, una cierta funcionalidad tomó menos de 5 segundos. Esta semana, después de instalar una actualización, la misma funcionalidad lleva más de 1 minuto.

    • Esta es una comparación con un rendimiento previamente comparado. El cliente mantiene el rendimiento futuro en un criterio absoluto de una escala de tiempo humana (de segundos a minutos).
  • Envié 100 trabajos al sistema. ¿Por qué tarda 400 veces más tiempo en procesar, en comparación con el tiempo que lleva un solo trabajo?

    • El cliente espera que el tiempo de procesamiento sea lineal. De hecho, el cliente no puede entender o aceptar que existen tareas que son más lentas que lineales.

Por esta razón, un cliente considerará que el tiempo de ejecución es un error si ambas son verdaderas:

  • Más lento que lineal
  • Notable (es decir, cae dentro del rango de tiempo humano (más de segundos o minutos) dados los tamaños de tarea típicos)

Argumentos legítimos que explican que un algoritmo de tiempo de ejecución cuadrático no plantea un problema (es decir, no merece un cambio de código):

  • El tamaño de la tarea que normalmente maneja esta función de tiempo de ejecución cuadrático está algo limitado
  • Dado el rango de tamaño típico, el tiempo de ejecución real (absoluto) sigue siendo lo suficientemente pequeño como para descartarlo
  • Si un usuario realmente intenta enviar una tarea que sea lo suficientemente grande como para que se note, el usuario recibirá un mensaje de advertencia sobre el largo tiempo de ejecución
  • Los usuarios del sistema son todos expertos, por lo tanto, saben lo que están haciendo. Por ejemplo, los usuarios de una API deberían haber leído la letra pequeña en la documentación de la API.

Muchos algoritmos útiles para el desarrollo de aplicaciones típicas son, de hecho, más lentos que los lineales (principalmente O (N log N), como en la ordenación), por lo tanto, el software a gran escala tratará de solucionarlo, solo ordenando la parte relevante de la aplicación. datos, o use técnicas de filtrado de histograma (estadística) que logren un efecto similar.

Esto se aplica a los clientes de software, pero si considera que los usuarios de una biblioteca de software o función API también son "clientes", entonces la respuesta aún se aplicaría.

rwong
fuente
2

Si el algoritmo original se implementó correctamente (o cualquier error fuera irrelevante), entonces "cambiar el algoritmo" o "sustitución del algoritmo" , ya que dichos cambios significan que está haciendo precisamente eso; sustituyendo un algoritmo con diferente complejidad de tiempo por el utilizado previamente.

Si la complejidad del tiempo anterior se debió a un error en la implementación (por ejemplo, digamos que estaba restableciendo accidentalmente el punto de inicio de un bucle interno en una secuencia de modo que lo que debería haber sido O (n) se convirtió en O (n 2 )), entonces "arreglar un error de costo cuadrático " o similar.

Hay una superposición, en ese caso el efecto en el código es el mismo si se sabe desde el principio que el trabajo se pudo hacer en tiempo O (n) y el tiempo O (n 2 ) fue un error, o si primero lo implementó deliberadamente en el tiempo O (n 2 ) y luego se dio cuenta de que todavía funcionaría correctamente sin restablecer el punto de partida, y así sustituyó un algoritmo O (n) por uno O (n 2 ).

Jon Hanna
fuente
1

Optimización de velocidad por orden / órdenes de magnitud. Aunque este es un lenguaje matemáticamente incorrecto, transmite mejor la idea de que se cambie la Orden.

Mejora la escalabilidad. escuchado también.

Joop Eggen
fuente