Modismos del lenguaje Java
1. ciclo
En bucles importantes, elimine las llamadas a métodos al determinar la terminación del bucle.
Por ejemplo: voluntad
for(int i=0; i<colección.size();i++){ ... }
Reemplazar con…
for(int i=0; n=colección.size();i<n;i++){...}
Por lo general, mueva los elementos que no están relacionados con el índice del bucle fuera del bucle.
for(int i=0; terminal=x.length;i<terminal;i++){x[i] = x[i]/scaleA *scaleB;}
Debería ser:
Doble escala = escalaB*escalaA;for(int i=0; terminal=x.length;i<terminal;i++){x[i] = x[i]/escala;}
2. cadena
Eliminar la concatenación de cadenas
Al crear cadenas largas, utilice siempre StringBuffter en lugar de String
Preasignar espacio StringBuffer StringBuffer sb = new StringBuffer(5000);
3. Tipos de datos básicos
Utilice tipos de datos básicos en bucles importantes (los datos int suelen ser más rápidos que los datos largos/dobles)
Las clases de ajuste de tipos de datos básicos (booleano, entero, etc.) se utilizan principalmente cuando el parámetro del método pasado debe ser una referencia a un objeto (en lugar de un tipo de datos básico).
Utilice el modificador final estático en todas las expresiones algebraicas constantes para facilitar la referencia a las constantes (el compilador precalcula las expresiones constantes)
4. anormal
Las excepciones solo se usan para una única condición de error verdadera, por lo que lanzar una excepción y ejecutar un bloque catch es costoso (principalmente debido a la obtención de una instantánea de la pila de subprocesos al crear una excepción).
Se lanza una excepción sólo cuando la condición es realmente excepcional. Para lanzar una excepción, primero se crea un nuevo objeto.
El constructor de la interfaz Throwable llama al método nativo llamado fillInStackTrace(). El método fillInStackTrace() verifica la pila y recopila información de seguimiento de llamadas.
Cada vez que se produce una excepción, la VM tiene que ajustar la pila de llamadas porque se crea un nuevo objeto durante el procesamiento.
Las excepciones solo deben usarse para el manejo de errores y no deben usarse para controlar el flujo del programa.
Realice optimizaciones del compilador y del tiempo de ejecución colocando varias llamadas a métodos en un bloque try/catch en lugar de implementar varios bloques try/catch para cada llamada a método.
try{ Some.method1(); //Difficut para java1.4 }catch(method1Exception e){ manejar excepción
1 // para optimizar este código } try{ Some.method2(); //Difficut para java1.4 }catch(method2Exception e){ manejar excepción
2 // para optimizar este código } try{ Some.method3(); //Difficut para java1.4 }catch(method3Exception e){ manejar excepción
3 // para optimizar este código
}
debe escribirse como:
try{ Some.method1(); Some.method2(); Some.method3(); //Difficut para java1.4 }catch(method1Exception e){ manejar excepción 1 }catch(method2Exception e){ manejar excepción 2 }catch( método3Exception e){manejar la excepción 3}
5. punto de referencia
Tenga en cuenta que todos estos consejos variarán entre plataformas y máquinas virtuales.
Por ejemplo: en algunos contenedores de servlets, es más rápido generar bytes a través de un OutputStream.
2. En otros contenedores, será más rápido generar caracteres a través de un PrintWriter.
Estos consejos describen las recomendaciones más portátiles.
Es posible que necesites ejecutar algunos puntos de referencia para determinar qué es más rápido en tu plataforma.
6. Crea una instancia de una clase sin usar la nueva palabra clave
Cuando crea una instancia de una clase usando la nueva palabra clave, todos los constructores en la cadena de constructores se llaman automáticamente.
Pero si un objeto implementa la interfaz Cloneable, podemos llamar a su método clone(). El método clone() no llama a ningún constructor de clase.
Cuando usa Design Pattern, si usa el modo Factory para crear un objeto, es muy simple usar el método clone() para crear una nueva instancia de objeto.
Por ejemplo, la siguiente es una implementación típica del patrón Factory:
Crédito estático público getNewCredit() { return new Credit() }
Después de la optimización:
Crédito estático privado BaseCredit = nuevo Crédito(); Crédito estático público getNewCredit() { return (Crédito) BaseCredit.clone();}
Las ideas anteriores también son útiles para el procesamiento de matrices.
7. Usar E/S sin bloqueo
Los JDK con versiones anteriores de Java no admiten API de E/S sin bloqueo. Para evitar el bloqueo de E/S, algunas aplicaciones crean una gran cantidad de subprocesos (en el mejor de los casos, se utiliza un grupo de búfer). Esta técnica se puede ver en muchas aplicaciones que deben soportar flujos de E/S concurrentes, como servidores web, aplicaciones de cotización y subasta, etc. Sin embargo, la creación de subprocesos Java requiere una sobrecarga considerable.
JDK 1.4 introdujo una biblioteca de E/S sin bloqueo (java.nio). Si su aplicación requiere una versión anterior del JDK, existe un paquete que admite E/S sin bloqueo.
8. No inicialice variables repetidamente
De forma predeterminada, al llamar al constructor de una clase, Java inicializará las variables con ciertos valores: todos los objetos se establecen en nulo, las variables enteras (byte, short, int, long) se establecen en 0 y las variables flotantes y dobles se establecen en 0.0, el valor lógico se establece en falso.
Esto debe tenerse en cuenta especialmente cuando una clase se deriva de otra clase, porque cuando se crea un objeto utilizando la nueva palabra clave, todos los constructores de la cadena de constructores se llamarán automáticamente.
9. Intenta especificar el modificador final de la clase.
Las clases con el modificador final no se derivan. En la API principal de Java, hay muchos ejemplos de aplicación de final, como java.lang.String. Especificar final para la clase String evita que las personas anulen el método length().
Además, si una clase se designa como final, todos los métodos de esa clase serán finales. El compilador de Java buscará oportunidades para incorporar todos los métodos finales (esto depende de la implementación específica del compilador). Esto puede mejorar el rendimiento en una media del 50%.
10. Utilice variables locales siempre que sea posible
Los parámetros pasados al llamar al método y las variables temporales creadas durante la llamada se guardan en la pila (Stack), que es más rápido. Otras variables, como variables estáticas, variables de instancia, etc., se crean en el montón y son más lentas. Además, dependiendo del compilador/JVM específico, las variables locales pueden optimizarse aún más. Consulte Usar variables de pila siempre que sea posible.
11. Multiplicación y división
Considere el siguiente código:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; miResultado = val * 2;
Después de la optimización:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; miResultado = val << 1;
El código modificado ya no realiza la operación de multiplicar por 8, sino que utiliza la operación equivalente de desplazar 3 bits hacia la izquierda. Cada desplazamiento hacia la izquierda de 1 bit equivale a multiplicar por 2. En consecuencia, una operación de desplazamiento a la derecha de 1 bit equivale a dividir por 2. Cabe mencionar que aunque la operación de cambio es rápida, puede hacer que el código sea más difícil de entender, por lo que es mejor agregar algunos comentarios.
Crédito estático privado BaseCredit = nuevo Crédito(); Crédito estático público getNewCredit() {return (Crédito) BaseCredit.clone();}