¿Cuáles son algunos de los fragmentos de código más ineficientes que has visto en el trabajo?

Lo que he visto en el código de producción fue, desde el punto de vista de la velocidad de ejecución, en realidad no tan malo, la mayoría de las veces. He visto bucles como este:

para (int i = 0; i <someContainer.GetSize (); ++ i)

{

// Haz algo con el elemento i

}

donde obtener el tamaño (o la longitud) tenía O (n) complejidad de tiempo de ejecución, lo que efectivamente hace que el código anterior O (n ^ 2). Entonces supongo que mucho código ineficiente tiene que ver con anteponer cadenas o calcular expresiones de cadena, pero como esto a menudo no ocurre en un bucle, no es tan malo.

También el código para analizar cadenas puede ser bastante ineficiente. En el código actual tenemos un bucle y dentro de ese bucle usan IndexOf () para buscar un byte de inicio o detención. Bueno, ¿adivina qué hace IndexOf? Se repite también …

Otra clase de ineficiencias puede ser causada por la falta de conocimiento matemático. Por ejemplo, ¿quién calcula la suma de 1 a 1,000,000,000 agregando un ciclo? Una vez probé con doble inducción que siempre se puede encontrar un polinomio de grado (n + 1) para sumar términos de grado n, entonces para la suma de x ^ 1, x ^ 2, x ^ 3 o x ^ n … para x en algún rango, hay un polinomio de 2º, 3er, 4to,… (n + 1) grado que le da la respuesta de inmediato.

A veces, el código es ineficiente, porque el problema es NP difícil. Hay muchos problemas para los cuales no se conocen mejores algoritmos que buscar en todo el espacio de búsqueda.

A partir de ejemplos de codificación, la famosa implementación ingenua de los números de Fibonacci es un muy buen ejemplo de código muy ineficiente. Por algunas razones, no he visto muchos algoritmos recursivos (excepto el qsort estándar) en el código de producción y, por lo tanto, no este tipo de explosión de ineficiencia. Pero sospecho que en muchas compañías donde tienen sus propios analizadores locales (! = Yacc + lex, o Boost spirit o ANTLR, etc.) de algún tipo u otras formas de recursión, encontrará ejemplos impactantes.

He visto mi parte justa, principalmente en la forma de “¿Por qué harías algo como esto?” en lugar de “Estás calculando algo en tiempo O (n ^ 2) cuando podrías calcularlo en tiempo O (log n)”.

Mi favorito actual es esta pequeña joya de Python:

Definición de formato Versión (v):
si v <10:
devuelve ‘00% d ‘% v
más:
si v <100:
devuelve ‘0% s’% v
más:
devuelve ‘% s’% v

Este es un gran ejemplo de reimplementación de una función de biblioteca integrada o estándar que simplemente podría codificarse como:

‘% 03d’% v

O como:

Formato ‘{: 03d}’. (V)

O incluso como:

str (v) .zfill (3)

Hay varias formas estándar de hacerlo que son más legibles y mantenibles. Es cierto que el desarrollador que lo escribió era nuevo en Python en ese momento. Sin embargo, tomar cinco minutos para ver qué características de formato de cadena tenía Python habría ahorrado la misma cantidad de tiempo (o más) para implementar una versión deficiente que también hincha la base de código.

El código de arenque rojo como este desperdicia el tiempo del programador, que es aún más importante que el tiempo de la máquina. Esto desperdicia el tiempo del programador cuando busca o escanea visualmente el código o simplemente intenta codificar el código como se ve arriba, pensando que hay algo que debe perderse, porque “¿Quién en su sano juicio escribiría algo tan obviamente redundante? Debe haber algo más que no veo “.

Todos nosotros escribimos código como este de vez en cuando, ya sea porque estamos cansados, distraídos o simplemente estamos en una mentalidad diferente para un dominio de problema diferente y no recordamos que existan mejores soluciones. Pero es por eso que las revisiones de código son importantes; cosas como esta quedan atrapadas antes de pasar a producción.

Oh hombre, ni siquiera sé por dónde empezar. En una base de código de producción, he visto algo que básicamente era esto

info_dict = eval (str (info_dict))

AFAIK, esta es una función de identidad, lo que entra, sale, creo que podría estar tratando de limpiar los datos de alguna manera, pero esta es claramente la forma menos útil de hacer cosas así.

Después de quince ifs anidados, una cadena se establece en “Objeto”. Se parece a esto:

if (a == verdadero) {
if (b == verdadero && c) {

labelMessage.text = “Objeto”;

}
}