Si tuviera que repetir un ciclo 7 veces, ¿usaría:
for (int i = 0; i < 7; i++)
o:
for (int i = 0; i <= 6; i++)
Hay dos consideraciones:
- actuación
- legibilidad
Para el rendimiento, supongo Java o C #. ¿Importa si se usa "menor que" o "menor o igual que"? Si tiene conocimiento de un idioma diferente, indique cuál.
Para facilitar la lectura, estoy asumiendo matrices basadas en 0.
UPD: Mi mención de matrices basadas en 0 puede haber confundido las cosas. No estoy hablando de iterar a través de elementos de matriz. Solo un bucle general.
Hay un buen punto a continuación sobre el uso de una constante para explicar qué es este número mágico. Así que si tuviera " int NUMBER_OF_THINGS = 7
" entonces " i <= NUMBER_OF_THINGS - 1
" se vería raro, ¿no?
performance
conventions
readability
Eugene Katz
fuente
fuente
Respuestas:
El primero es más idiomático . En particular, indica (en un sentido basado en 0) el número de iteraciones. Al usar algo basado en 1 (por ejemplo, JDBC, IIRC), podría sentir la tentación de usar <=. Entonces:
Esperaría que la diferencia de rendimiento sea insignificantemente pequeña en el código del mundo real.
fuente
Ambos bucles iteran 7 veces. Yo diría que el que tiene un 7 es más legible / más claro, a menos que tenga una buena razón para el otro.
fuente
Recuerdo de mis días cuando hicimos la Asamblea 8086 en la universidad, fue más eficiente:
ya que hubo una operación JNS que significa Saltar si no hay señal. Usar esto significaba que no había búsqueda de memoria después de cada ciclo para obtener el valor de comparación y tampoco comparar. En la actualidad, la mayoría de los compiladores optimizan el uso del registro, por lo que la memoria ya no es importante, pero aún así obtiene una comparación no requerida.
Por cierto, poner 7 o 6 en tu ciclo es introducir un " número mágico ". Para una mejor legibilidad, debe usar una constante con un nombre revelador de intención. Me gusta esto:
EDITAR: La gente no está entendiendo el montaje, por lo que obviamente se requiere un ejemplo más completo:
Si lo hacemos para (i = 0; i <= 10; i ++) debe hacer esto:
Si lo hacemos para (int i = 10; i> -1; i--), entonces puede salirse con la suya:
Acabo de comprobar y el compilador de C ++ de Microsoft no hace esta optimización, pero lo hace si usted lo hace:
Entonces, la moraleja es que si está utilizando Microsoft C ++ †, y ascendente o descendente no hace ninguna diferencia, para obtener un bucle rápido debe usar:
en lugar de cualquiera de estos:
Pero, francamente, obtener la legibilidad de "for (int i = 0; i <= 10; i ++)" es normalmente mucho más importante que perder un comando de procesador.
† Otros compiladores pueden hacer cosas diferentes.
fuente
7-i
que va a empañar cualquier optimización que obtenga al contar hacia atrás.Siempre uso <array.length porque es más fácil de leer que <= array.length-1.
también con <7 y dado que sabe que está comenzando con un índice 0, debería ser intuitivo que el número es el número de iteraciones.
fuente
Visto desde un punto de vista optimizador, no importa.
Visto desde un punto de vista de estilo de código, prefiero <. Razón:
es mucho más legible que
también <te da el número de iteraciones de inmediato.
Otro voto a favor de <es que podría evitar muchos errores accidentales ocasionales.
fuente
@ Chris, su afirmación sobre que .Length es costoso en .NET en realidad no es cierto y, en el caso de los tipos simples, es exactamente lo contrario.
en realidad es más lento que
El último es un caso optimizado por el tiempo de ejecución. Dado que el tiempo de ejecución puede garantizar que i es un índice válido en la matriz, no se realizan verificaciones de límites. En el primero, el tiempo de ejecución no puede garantizar que no haya sido modificado antes del ciclo y obliga a las verificaciones de límites en la matriz para cada búsqueda de índice.
fuente
.lenght
OR.size
. No estoy seguro pero no estoy seguro, pero solo quiero asegurarme.No hace una diferencia efectiva cuando se trata de rendimiento. Por lo tanto, usaría el que sea más fácil de entender en el contexto del problema que está resolviendo.
fuente
Yo prefiero:
Creo que eso se traduce más fácilmente a "iterar a través de un bucle 7 veces".
No estoy seguro de las implicaciones de rendimiento: sospecho que cualquier diferencia se compilaría.
fuente
En Java 1.5 solo puedes hacer
así que para el caso de la matriz no tienes que preocuparte.
fuente
No creo que haya una diferencia de rendimiento. Sin embargo, la segunda forma es definitivamente más legible, no es necesario restar mentalmente una para encontrar el último número de iteración.
EDITAR: veo que otros no están de acuerdo. Para mí personalmente, me gusta ver los números de índice reales en la estructura de bucle. Tal vez sea porque recuerda más a la
0..6
sintaxis de Perl , que sé que es equivalente a(0,1,2,3,4,5,6)
. Si veo un 7, tengo que verificar el operador al lado para ver que, de hecho, el índice 7 nunca se alcanza.fuente
Yo diría que use la versión "<7" porque eso es lo que leerá la mayoría de las personas, por lo que si las personas leen con descuido su código, podrían interpretarlo incorrectamente.
No me preocuparía si "<" es más rápido que "<=", solo busque legibilidad.
Si desea aumentar la velocidad, considere lo siguiente:
Para aumentar el rendimiento, puede reorganizarlo ligeramente para:
Observe la eliminación de GetCount () del bucle (porque se consultará en cada bucle) y el cambio de "i ++" a "++ i".
fuente
En C ++, prefiero usar
!=
, que se puede usar con todos los contenedores STL. No todos los iteradores de contenedores STL son menos que comparables.fuente
Edsger Dijkstra escribió un artículo sobre esto en 1982, donde argumenta a favor de <= i <superior:
fuente
Primero, no use 6 o 7.
Mejor usar:
En este caso es mejor que usar
Aún mejor (Java / C #):
Y aún mejor (C #)
El ciclo inverso es realmente más rápido, pero dado que es más difícil de leer (si no lo hacen otros programadores), es mejor evitarlo. Especialmente en C #, Java ...
fuente
Estoy de acuerdo con la multitud que dice que el 7 tiene sentido en este caso, pero agregaría que en el caso donde el 6 es importante, digamos que desea dejar en claro que solo está actuando sobre objetos hasta el sexto índice, luego el <= es mejor ya que hace que los 6 sean más fáciles de ver.
fuente
En la universidad, recuerdo algo acerca de que estas dos operaciones son similares en el tiempo de cálculo en la CPU. Por supuesto, estamos hablando a nivel de montaje.
Sin embargo, si estás hablando de C # o Java, realmente no creo que uno vaya a aumentar la velocidad sobre el otro, los pocos nanosegundos que obtienes probablemente no valen la confusión que introduzcas.
Personalmente, crearía el código que tiene sentido desde el punto de vista de la implementación comercial y me aseguraría de que sea fácil de leer.
fuente
Esto cae directamente bajo la categoría de "Hacer que el código incorrecto parezca incorrecto" .
En los lenguajes de indexación basados en cero, como Java o C #, las personas están acostumbradas a las variaciones de la
index < count
condición. Por lo tanto, aprovechar esta convención de facto haría que los errores fuera de uno sean más obvios.En cuanto al rendimiento: cualquier buen compilador que valga la huella de su memoria debería ser un problema.
fuente
Como un pequeño aparte, al recorrer una matriz u otra colección en .Net, encuentro
para ser más legible que el bucle numérico para. Por supuesto, esto supone que el contador real Int no se usa en el código del bucle. No sé si hay un cambio de rendimiento.
fuente
Hay muchas buenas razones para escribir i <7. Tener el número 7 en un bucle que itera 7 veces es bueno. El rendimiento es efectivamente idéntico. Casi todo el mundo escribe i <7. Si está escribiendo para facilitar la lectura, use el formulario que todos reconocerán al instante.
fuente
Siempre he preferido:
fuente
Tener el hábito de usar <lo hará consistente tanto para usted como para el lector cuando esté iterando a través de una matriz. Será más simple para todos tener una convención estándar. Y si está utilizando un lenguaje con matrices basadas en 0, entonces <es la convención.
Esto casi ciertamente importa más que cualquier diferencia de rendimiento entre <y <=. Apunte a la funcionalidad y la legibilidad primero, luego optimice.
Otra nota es que sería mejor tener el hábito de hacer ++ i en lugar de i ++, ya que fetch and increment requiere un temporal e increment y fetch no. Para los enteros, su compilador probablemente optimizará la eliminación temporal, pero si su tipo de iteración es más complejo, es posible que no pueda hacerlo.
fuente
No uses números mágicos.
¿Por qué son las 7? (o 6 para el caso).
use el símbolo correcto para el número que desea usar ...
En cuyo caso creo que es mejor usar
fuente
Los operadores '<' y '<=' son exactamente el mismo costo de rendimiento.
El operador '<' es un estándar y más fácil de leer en un bucle de base cero.
Usar ++ i en lugar de i ++ mejora el rendimiento en C ++, pero no en C #: no sé acerca de Java.
fuente
Como la gente ha observado, no hay diferencia en ninguna de las dos alternativas que mencionó. Solo para confirmar esto, hice algunos benchmarking simples en JavaScript.
Puedes ver los resultados aquí . Lo que no está claro de esto es que si cambio la posición de la primera y segunda prueba, los resultados de esas 2 pruebas cambian, esto es claramente un problema de memoria. Sin embargo, la tercera prueba, una en la que invierto el orden de la iteración, es claramente más rápida.
fuente
Como todos dicen, es costumbre usar iteradores indexados 0 incluso para cosas fuera de los arrays. Si todo comienza en
0
y termina enn-1
, y los límites inferiores son siempre<=
y los límites superiores son siempre<
, hay mucho menos pensamiento que debe tener al revisar el código.fuente
Gran pregunta Mi respuesta: use el tipo A ('<')
i < strlen(s)
lugar del índice del último elemento, por lo que la uniformidad es importante.Otro problema es con toda esta construcción.
i
aparece 3 veces en él, por lo que se puede escribir mal. La construcción for-loop dice cómo hacer en lugar de qué hacer . Sugiero adoptar esto:BOOST_FOREACH(i, IntegerInterval(0,7))
Esto es más claro, se compila para ejecutar exactamente las mismas instrucciones, etc. Pídame el código de IntegerInterval si lo desea.
fuente
Tantas respuestas ... pero creo que tengo algo que agregar.
Mi preferencia es que los números literales muestren claramente qué valores tomará "i" en el ciclo . Entonces, en el caso de iterar a través de una matriz basada en cero:
for (int i = 0; i <= array.Length - 1; ++i)
Y si solo está haciendo un bucle, sin iterar a través de una matriz, contar de 1 a 7 es bastante intuitivo:
for (int i = 1; i <= 7; ++i)
La legibilidad supera el rendimiento hasta que lo perfiles, ya que probablemente no sepas qué hará el compilador o el tiempo de ejecución con tu código hasta entonces.
fuente
También podría usar
!=
en su lugar. De esa manera, obtendrá un bucle infinito si comete un error en la inicialización, lo que hace que el error se note antes y cualquier problema que cause se limite a quedarse atrapado en el bucle (en lugar de tener un problema mucho más tarde y no encontrarlo eso).fuente
Creo que ambos están bien, pero cuando hayas elegido, mantente en uno u otro. Si está acostumbrado a usar <=, intente no usar <y viceversa.
Prefiero <=, pero en situaciones en las que está trabajando con índices que comienzan en cero, probablemente intente usar <. Sin embargo, todo es preferencia personal.
fuente
Estrictamente desde un punto de vista lógico, debes pensar que
< count
sería más eficiente que<= count
por la razón exacta que también<=
probará la igualdad.fuente