El alcance de las variables locales siempre debe ser lo más pequeño posible.
En su ejemplo, supongo str
que no se usa fuera del while
bucle, de lo contrario no haría la pregunta, porque declararlo dentro del while
bucle no sería una opción, ya que no se compilaría.
Entonces, dado str
que no se usa fuera del ciclo, el alcance más pequeño posible str
está dentro del ciclo while.
Entonces, la respuesta es enfáticamente que str
absolutamente debe declararse dentro del ciclo while. Sin peros, sin peros, sin peros.
El único caso en el que podría violarse esta regla es si, por alguna razón, es de vital importancia que cada ciclo de reloj se elimine del código, en cuyo caso es posible que desee considerar crear una instancia de algo en un ámbito externo y reutilizarlo en lugar de volver a crear una instancia en cada iteración de un ámbito interno. Sin embargo, esto no se aplica a su ejemplo, debido a la inmutabilidad de las cadenas en java: siempre se creará una nueva instancia de str al comienzo de su ciclo y tendrá que desecharse al final de la misma, por lo que No hay posibilidad de optimizar allí.
EDITAR: (inyectando mi comentario a continuación en la respuesta)
En cualquier caso, la forma correcta de hacer las cosas es escribir todo su código correctamente, establecer un requisito de rendimiento para su producto, medir su producto final en función de este requisito y, si no lo cumple, ir a optimizar las cosas. Y lo que generalmente sucede es que encuentra formas de proporcionar algunas optimizaciones algorítmicas agradables y formales en solo un par de lugares que hacen que nuestro programa cumpla con sus requisitos de rendimiento en lugar de tener que revisar toda su base de código y modificar y piratear cosas en para apretar los ciclos de reloj aquí y allá.
Comparé el código de bytes de esos dos ejemplos (similares):
Veamos 1. ejemplo :
después
javac Test.java
,javap -c Test
obtendrás:Veamos 2. ejemplo :
después
javac Test.java
,javap -c Test
obtendrás:Las observaciones muestran que no hay diferencia entre esos dos ejemplos. Es el resultado de las especificaciones JVM ...
Pero en nombre de la mejor práctica de codificación, se recomienda declarar la variable en el alcance más pequeño posible (en este ejemplo, está dentro del bucle, ya que este es el único lugar donde se usa la variable).
fuente
final
amantes: declararstr
comofinal
en elinside
caso del paquete tampoco hace diferencia =)Declarar objetos en el ámbito más pequeño mejora la legibilidad .
El rendimiento no importa para los compiladores de hoy. (En este escenario)
Desde una perspectiva de mantenimiento, la segunda opción es mejor.
Declare e inicialice las variables en el mismo lugar, en el ámbito más estrecho posible.
Como dijo Donald Ervin Knuth :
es decir, la situación en la que un programador deja que las consideraciones de rendimiento afecten el diseño de un fragmento de código. Esto puede dar como resultado un diseño que no es tan limpio como podría haber sido o un código incorrecto, porque la optimización complica el código y el optimizador distrae al programador .
fuente
si quieres usar el
str
bucle externo también; declararlo afuera. de lo contrario, la segunda versión está bien.fuente
Pase a la respuesta actualizada ...
Para aquellos que se preocupan por el rendimiento, saque System.out y limite el ciclo a 1 byte. Usando doble (prueba 1/2) y usando Cadena (3/4), los tiempos transcurridos en milisegundos se muestran a continuación con Windows 7 Professional de 64 bits y JDK-1.7.0_21. Los códigos de bytes (que también se proporcionan a continuación para test1 y test2) no son lo mismo. Era demasiado vago para probar con objetos mutables y relativamente complejos.
doble
Prueba1 tomó: 2710 ms
Test2 tomó: 2790 ms
Cadena (solo reemplace doble con cadena en las pruebas)
Test3 tomó: 1200 ms
Test4 tomó: 3000 ms
Compilar y obtener bytecode
RESPUESTA ACTUALIZADA
Realmente no es fácil comparar el rendimiento con todas las optimizaciones de JVM. Sin embargo, es algo posible. Mejor prueba y resultados detallados en Google Caliper
Código de prueba parcial para doble declaración
Esto no es idéntico al código anterior. Si solo codifica un bucle ficticio, JVM lo omite, por lo que al menos debe asignar y devolver algo. Esto también se recomienda en la documentación de Caliper.
fuente
Una solución a este problema podría ser proporcionar un alcance variable que encapsule el ciclo while:
Serían automáticamente desreferenciados cuando finalice el alcance externo.
fuente
En el interior, cuanto menos alcance sea visible la variable, mejor.
fuente
Si no necesita usar el
str
bucle while (relacionado con el alcance), entonces la segunda condición, es decires mejor ya que si define un objeto en la pila solo si
condition
es verdadero. Es decir, úsalo si lo necesitasfuente
Creo que el mejor recurso para responder a su pregunta sería la siguiente publicación:
¿Diferencia entre declarar variables antes o en bucle?
Según tengo entendido, esto dependería del idioma. IIRC Java optimiza esto, por lo que no hay ninguna diferencia, pero JavaScript (por ejemplo) hará toda la asignación de memoria cada vez en el bucle. En Java, particularmente, creo que el segundo se ejecutará más rápido cuando termine el perfil.
fuente
Como mucha gente ha señalado,
NO es mejor que esto:
Por lo tanto, no declare variables fuera de su alcance si no lo está reutilizando ...
fuente
Declarar String str fuera del bucle wile permite que se haga referencia dentro y fuera del bucle while. Declarar String str dentro del ciclo while permite que solo se haga referencia dentro del ciclo while.
fuente
Las variables deben declararse lo más cerca posible del lugar donde se usan.
Facilita la RAII (Adquisición de recursos es inicialización) .
Mantiene el alcance de la variable ajustado. Esto permite que el optimizador funcione mejor.
fuente
Según la guía de desarrollo de Google Android, el alcance variable debe ser limitado. Por favor revise este enlace:
Alcance variable límite
fuente
La
str
variable estará disponible y reservará algo de espacio en la memoria incluso después de ejecutarse debajo del código.La
str
variable no estará disponible y también se liberará la memoria que se asignó para lastr
variable en el siguiente código.Si seguimos el segundo seguramente esto reducirá la memoria de nuestro sistema y aumentará el rendimiento.
fuente
Declarar dentro del ciclo limita el alcance de la variable respectiva. Todo depende del requisito del proyecto en el alcance de la variable.
fuente
En verdad, la pregunta mencionada anteriormente es un problema de programación. ¿Cómo le gustaría programar su código? ¿Dónde necesita el 'STR' para acceder? No tiene sentido declarar una variable que se usa localmente como una variable global. Conceptos básicos de programación, creo.
fuente
Estos dos ejemplos dan como resultado lo mismo. Sin embargo, el primero le proporciona el uso de la
str
variable fuera del ciclo while; El segundo no lo es.fuente
Advertencia para casi todos en esta pregunta: Aquí hay un código de muestra en el que dentro del bucle puede ser fácilmente 200 veces más lento en mi computadora con Java 7 (y el consumo de memoria también es ligeramente diferente). Pero se trata de la asignación y no solo del alcance.
Conclusión: Dependiendo del tamaño de la variable local, la diferencia puede ser enorme, incluso con variables no tan grandes.
Solo para decir que a veces, fuera o dentro del circuito sí importa.
fuente
bigStuff[(int) (value % STUFF_SIZE)] = value;
(Pruebe un valor de 2147483649L)Creo que el tamaño del objeto también importa. En uno de mis proyectos, habíamos declarado e inicializado una gran matriz bidimensional que estaba haciendo que la aplicación lanzara una excepción de falta de memoria. En su lugar, retiramos la declaración del ciclo y borramos la matriz al comienzo de cada iteración.
fuente
Corre el riesgo de
NullPointerException
que sucalculateStr()
método devuelva nulo y luego intente llamar a un método en str.De manera más general, evite tener variables con un valor nulo . Es más fuerte para los atributos de clase, por cierto.
fuente
NullPointerException.
Si este código intentarareturn str;
encontrar un error de compilación.