Pregunta

String s = "";
for(i=0;i<....){
    s = some Assignment;
}

o

for(i=0;i<..){
    String s = some Assignment;
}

No es necesario el uso de 's' fuera del bucle nunca más.La primera opción es quizás mejor, ya que una nueva Cadena no se inicializa cada vez.La segunda sin embargo, el resultado sería en el ámbito de aplicación de la variable está limitada al bucle de sí mismo.

EDITAR:En respuesta a Milhous la respuesta.Sería inútil para asignar la Cadena a una constante dentro de un bucle no?No, aquí algunos Asignación " significa un cambio de valor obtenido de la lista que se itera a través de.

También, la pregunta no es porque estoy preocupado por la gestión de la memoria.Solo quiero saber cual es mejor.

¿Fue útil?

Solución

Alcance limitado es el Mejor

Utilizar la segunda opción:

for ( ... ) {
  String s = ...;
}

Ámbito de aplicación no Afecta el Rendimiento

Si desarmas el código compilado a partir de cada uno (con el JDK de la javap la herramienta), verá que el bucle se compila a exactamente la misma JVM instrucciones en ambos casos.Tenga en cuenta también que Brian R.Bondy del "La opción #3" es idéntico al de la Opción #1.No hay nada extra que se agrega o se quita de la pila cuando se utiliza en el más estricto ámbito de aplicación, y los mismos datos se utilizan en la pila en ambos casos.

Evitar La Prematura Inicialización

La única diferencia entre los dos casos es que, en el primer ejemplo, la variable s es innecesariamente inicializado.Esta es una cuestión independiente de la ubicación de la declaración de la variable.Esto añade dos desperdicio de instrucciones (para cargar una constante de cadena y guárdelo en un marco de pila de la ranura).Una buena herramienta de análisis estático le advertirá de que nunca estás leyendo el valor que asigne a s, y un buen compilador JIT probablemente se elide en tiempo de ejecución.

Se podría arreglar esto simplemente mediante el uso de un vacío declaración (es decir, String s;), pero esto se considera mala práctica y tiene otro efecto secundario discuten a continuación.

A menudo un falso valor como null se asigna a una variable simplemente para silenciar a un error del compilador que una variable es leer sin ser inicializado.Este error puede ser tomado como un indicio de que el ámbito de la variable es demasiado grande, y que se declara antes de que sea necesario para recibir un valor válido.Declaraciones vacías fuerza a considerar cada ruta de acceso del código;no ignore esta valiosa advertencia mediante la asignación de un falso valor.

Conservar La Pila De Ranuras

Como se ha mencionado, mientras que la JVM instrucciones son las mismas en ambos casos, hay un sutil efecto secundario que hace que sea mejor, en una JVM nivel, para utilizar el más limitado ámbito de aplicación posible.Esto es visible en el "local de la tabla de variables" para el método.Considere lo que sucede si usted tiene varios bucles, con las variables declaradas en innecesariamente gran alcance:

void x(String[] strings, Integer[] integers) {
  String s;
  for (int i = 0; i < strings.length; ++i) {
    s = strings[0];
    ...
  }
  Integer n;
  for (int i = 0; i < integers.length; ++i) {
    n = integers[i];
    ...
  }
}

Las variables s y n podría ser declaradas dentro de sus respectivos bucles, pero ya no lo son, el compilador utiliza dos "slots" en el marco de pila.Si ellos fueron declarados dentro del bucle, el compilador puede reutilizar la misma ranura, haciendo que el marco de pila más pequeña.

Lo Que Realmente Importa

Sin embargo, la mayoría de estos problemas son insignificantes.Un buen compilador JIT va a ver que no es posible leer el valor inicial que se pierde la asignación, y optimizar la asignación de distancia.El ahorro de una ranura de aquí o de allí no se va a hacer o romper su aplicación.

Lo importante es hacer que tu código sea legible y fácil de mantener, y en ese sentido, el uso de un alcance limitado es claramente mejor.El ámbito más reducido de una variable tiene, más fácil es de comprender cómo se utiliza y cuál es el impacto de cualquier cambio en el código que va a tener.

Otros consejos

En la teoría de la, es un desperdicio de recursos para declarar la cadena dentro del bucle.En la práctica, sin embargo , tanto de los fragmentos que se presentan compilará hasta el mismo código (declaración fuera del bucle).

Así, si el compilador hace cualquier cantidad de optimización, no hay ninguna diferencia.

En general, yo elegiría la segunda, porque el ámbito de aplicación de la 's' variable está limitada al bucle.Beneficios:

  • Esto es mejor para el programador, porque usted no tiene que preocuparse acerca de la 's' se usa de nuevo en algún lugar más adelante en la función
  • Esto es mejor para el compilador debido a que el alcance de la variable es menor, y por lo que potencialmente puede hacer más análisis y optimización
  • Esto es mejor para los futuros lectores, ya que no es de extrañar por qué la 's' de la variable es declarada fuera del bucle si nunca utiliza más adelante

Si desea acelerar para los bucles, prefiero declarar un máximo variable al lado del contador, por lo que no repite las búsquedas de las condidtion son necesarios:

en lugar de

for (int i = 0; i < array.length; i++) {
  Object next = array[i];
}

Yo prefiero

for (int i = 0, max = array.lenth; i < max; i++) {
  Object next = array[i];
}

Cualquier otra cosas que deben ser consideradas ya se han mencionado, por lo que sólo mis dos centavos (véase ericksons post)

Saludos, GHad

Para agregar un poco a @Esteban Araya respuesta, ambos requieren la creación de una nueva cadena en cada iteración del bucle (como el valor de retorno de la some Assignment de expresión).Las cadenas deben ser de basura recogida de cualquier manera.

Sé que esto es una vieja pregunta, pero pensé que me gustaría añadir un poco de lo que es ligeramente relacionados.

Me he dado cuenta mientras navega el código fuente de Java que algunos métodos, como la Cadena.contentEquals duplicado (abajo) hace redundante variables locales que no son más que copias de las variables de la clase.Creo que hubo un comentario en algún lugar, que implica que el acceso a las variables locales es más rápido que el acceso a las variables de clase.

En este caso, "v1" y "v2" son aparentemente innecesarias y podrían ser eliminadas para simplificar el código, pero se han añadido para mejorar el rendimiento.

public boolean contentEquals(StringBuffer sb) {
    synchronized(sb) {
        if (count != sb.length())
            return false;
        char v1[] = value;
        char v2[] = sb.getValue();
        int i = offset;
        int j = 0;
        int n = count;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
                return false;
        }
    }
    return true;
}

A mí me parece que necesitamos más de la especificación del problema.

El

s = some Assignment;

no se especifica a qué tipo de asignación es esto.Si la asignación es

s = "" + i + "";

a continuación, una nueva picadura se debe asignar.

pero si es

s = some Constant;

s simplemente seleccione las constantes de la localización de memoria, y por lo tanto la primera versión sería más eficiente de la memoria.

Parece que poco tonto que preocuparse mucho de la optimización de un bucle for para una interpretado lang en mi humilde opinión.

Cuando estoy usando múltiples hilos (50+) entonces me pareció que para ser una forma muy efectiva de manejo fantasma hilo de problemas con no ser capaz de cerrar un proceso correctamente ....si estoy equivocado, por favor hágamelo saber por qué estoy equivocado:

Process one;
BufferedInputStream two;
try{
one = Runtime.getRuntime().exec(command);
two = new BufferedInputStream(one.getInputStream());
}
}catch(e){
e.printstacktrace
}
finally{
//null to ensure they are erased
one = null;
two = null;
//nudge the gc
System.gc();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top