Detalles de optimización de código
1. Intente especificar que el modificador final de la clase y el método. No se pueden derivar clases con modificadores finales con modificadores finales. En la API de Java Core, hay muchos ejemplos de aplicación final, como java.lang.string, y toda la clase es definitiva. Especificar un modificador final para una clase puede evitar que la clase sea heredada, y especificar un modificador final para un método puede evitar que el método se anule. Si una clase se especifica como final, todos los métodos de esa clase son finales. El compilador Java buscará oportunidades para en línea todos los métodos finales. En línea es de gran importancia para mejorar la eficiencia de la operación de Java.
2. Intente reutilizar el uso de objetos, especialmente los objetos de cadena. Cuando se produce la concatenación de cadena, StringBuilder/StringBuffer debe usarse en su lugar. Dado que las máquinas virtuales de Java no solo necesitan pasar tiempo generando objetos, también es posible que también necesiten pasar el tiempo recolectando y procesando estos objetos en el futuro, sino que generar demasiados objetos tendrá un gran impacto en el rendimiento del programa.
3. Use variables locales para llamar a los métodos tanto como sea posible. Los parámetros pasados al llamar a los métodos y las variables temporales creadas en la llamada se almacenan en la pila más rápido. Se crean otras variables, como variables estáticas, variables de instancia, etc., y la velocidad es más lenta. Además, a medida que las variables creadas en la pila están terminadas, estos contenidos se han ido y no se requieren una recolección de basura adicional.
4. Cierre el flujo en el tiempo
Durante la programación de Java, tenga cuidado al realizar la conexión de la base de datos y las operaciones de transmisión de E/S. Después de su uso, cierre a tiempo para liberar recursos. Debido a que el funcionamiento de estos objetos grandes causará una sobrecarga del sistema grande, y si no tiene cuidado, conducirá a graves consecuencias.
5. Intente minimizar el cálculo repetido de variables, aclare un concepto. Incluso si solo hay una oración en el método, todavía se consume, incluida la creación de marcos de pila, proteger el sitio al llamar al método y restaurar el sitio al llamar al método. Entonces, por ejemplo, la siguiente operación:
para (inti = 0; i <list.size (); i ++)
{...} se recomienda reemplazarlo con:
para (inti = 0, longitud = list.size (); i <longitud; i ++)
{...}
De esta manera, cuando list.size () es muy grande, reduce mucho consumo
6. Trate de adoptar una estrategia de carga perezosa, es decir, crearla cuando sea necesario
7. Use las anormalidades con precaución será perjudicial para el rendimiento. Para lanzar una excepción, primero debe crear un nuevo objeto. El constructor de la interfaz de lanzamiento llama al método de sincronización local llamado FillinStackTrace (). El método FillinStackTrace () verifica la pila y recopila información de trazas de llamadas. Mientras se lance una excepción, la máquina virtual Java debe ajustar la pila de llamadas porque se crea un nuevo objeto durante el procesamiento. Las excepciones solo se pueden usar para el manejo de errores y no se deben usar para controlar el flujo del programa.
8. No uses intento ... Catch ... en el bucle, debe colocarse en la capa más externa
Según las opiniones presentadas por los internautas, creo que vale la pena discutir esto
9. Si puede estimar la longitud del contenido que se agregará, especifique la longitud inicial para la colección y las clases de herramientas implementadas en una matriz, como ArrayList, Linkedllist, StringBuilder, StringBuffer, Hashmap, Hashset, etc. Tome StringBuilder como ejemplo:
(1) StringBuilder () // predeterminado para asignar 16 caracteres (2) StringBuilder (int tize) // predeterminado para asignar 16 caracteres (3) StringBuilder (String STR) // predeterminado para asignar 16 caracteres + str.length () espacio de caracteres Puede establecer su capacidad de inicialización a través del constructor de la clase (aquí, aquí referimos no solo al stringBuilder anterior), lo que puede mejorar significativamente el rendimiento. Por ejemplo, StringBuilder, la longitud representa el número de caracteres que el StringBuilder actual puede mantener. Porque cuando StringBuilder alcanza su capacidad máxima, aumentará su capacidad a 2 veces y agregará 2. Siempre que StringBuilder alcance su capacidad máxima, tendrá que crear una nueva matriz de caracteres y copiar el contenido de matriz de personajes antiguos a la nueva matriz de caracteres; esta es una operación muy consumidor de rendimiento. Solo imagine, si puede estimar que 5000 caracteres se almacenan en la matriz de personajes sin especificar la longitud, el poder de 2 más cercano a 5000 es 4096, y los 2 agregados a cada expansión es independientemente de los 2, entonces: entonces:
(1) Basado en 4096, solicite matrices de personajes de tamaño 8194, que suman matrices de caracteres de tamaño 12290 a la vez. Si puede especificar matrices de caracteres de 5000 de tamaño al principio, ahorrará más del doble del espacio (2) copiar los 4096 caracteres originales en la nueva matriz de caracteres de esta manera, que no solo desperdiciará el espacio de memoria, sino que también reducirá la eficiencia de la operación del código. Por lo tanto, no es incorrecto establecer una capacidad de inicialización razonable para las clases de recopilación y herramientas implementadas en la matriz subyacente, que traerá resultados inmediatos. Sin embargo, tenga en cuenta que las colecciones como HASHMAP que se implementan en Arrays + Listas vinculadas no deben establecer el tamaño inicial igual que su tamaño estimado, porque la posibilidad de un solo objeto conectado a una tabla es casi 0. Se recomienda establecer el tamaño inicial en N potencia de 2. Si puede estimar que hay 2,000 elementos, establecerlo en New Hashmap (128) y New HaShMAP (256).
10. Al copiar una gran cantidad de datos, use el comando System.ArrayCopy ()
11. Multiplicación y división Uso de operaciones de turno
12. No cree referencias de objetos continuamente en el bucle
Por ejemplo:
for (inti = 1; i <= count; i ++) {object obj = newobject (); }Este enfoque hará que la referencia del objeto de conteo existente en la memoria. Si el recuento es grande, consumirá memoria. Se recomienda cambiarlo a:
Object obj = null; para (inti = 0; i <= count; i ++) {obj = newobject ();} De esta manera, solo hay una referencia de objeto de objeto en la memoria. Cada vez que se usa el nuevo objeto (), la referencia del objeto del objeto apunta a un objeto diferente, pero solo hay un objeto en la memoria, que guarda enormemente el espacio de la memoria.
13. Según la consideración de la eficiencia y la verificación de tipo, la matriz debe usarse tanto como sea posible. ArrayList debe usarse solo cuando el tamaño de la matriz no se puede determinar.
14. Intente usar hashmap, arraylist y stringbuilder. A menos que Thread-Safe lo requiera, no se recomienda usar Hashtable, Vector y StringBuffer. Los últimos tres tienen una sobrecarga de rendimiento debido al uso de mecanismos de sincronización.
15. No declare las matrices como final estática pública
Debido a que esto no tiene sentido, solo define la referencia como final estática, y el contenido de la matriz aún se puede cambiar a voluntad. Declarar la matriz como pública es una vulnerabilidad de seguridad, lo que significa que la matriz puede ser cambiada por clases externas
16. Intente usar singletons en ocasiones adecuadas. El uso de solteros puede reducir la carga de carga, acortar el tiempo de carga y mejorar la eficiencia de carga. Sin embargo, no todos los lugares son adecuados para singletons. En pocas palabras, los singletons son principalmente aplicables a los siguientes tres aspectos:
(1) Controle el uso de recursos, controle el acceso concurrente de los recursos a través de la sincronización de hilos (2) Controle la generación de instancias para lograr el propósito de ahorrar recursos (3) controlar el intercambio de datos y permitir la comunicación entre múltiples procesos o hilos no relacionados sin establecer asociaciones directas sin establecer asociaciones directas.
17. Trate de evitar usar variables estáticas a voluntad
Clase pública A {PRIVADA ESTÁTICA b b = newB (); } En este momento, el ciclo de vida de la variable estática B es el mismo que el de la Clase A. Si la Clase A no está desinstalado, el objeto B señalado por referencia B residirá en la memoria hasta que el programa termine
18. Claro que ya no necesitan sesiones en el tiempo. Para eliminar las sesiones ya no activas, muchos servidores de aplicaciones tienen un tiempo de espera de sesión predeterminado, generalmente 30 minutos. Cuando el servidor de aplicaciones necesita guardar más sesiones, si no hay memoria insuficiente, el sistema operativo transferirá parte de los datos al disco. El servidor de aplicaciones también puede arrojar algunas sesiones inactivas al disco de acuerdo con el algoritmo MRU (más utilizado recientemente), e incluso puede arrojar excepciones de memoria insuficientes. Si la sesión debe ser arrojada al disco, primero debe ser serializada. En grupos a gran escala, la serialización de los objetos es costoso. Por lo tanto, cuando la sesión ya no es necesaria, el método Invalidate () de httpsession debe llamarse a tiempo para borrar la sesión.
19. Para las colecciones que implementan interfaces RandomAccess, como ArrayList, debe usar el bucle más común en lugar de foreach Loop para atravesar esto es recomendado por JDK a los usuarios. La explicación de la API JDK de la interfaz RandomAccess es: la implementación de la interfaz RandomAccess se utiliza para indicar que admite un acceso aleatorio rápido. El objetivo principal de esta interfaz es permitir que los algoritmos generales cambien su comportamiento, para que pueda proporcionar un buen rendimiento cuando se aplica a listas de acceso aleatorias o continuas. La experiencia práctica muestra que si se acceden al azar las instancias de clase que implementan la interfaz RandomAccess, la eficiencia del uso de bucles ordinarios para los bucles será mayor que la de usar bucles foreach; Por el contrario, si se accede secuencialmente, será más eficiente usar Iterator. Puede usar códigos similares a los siguientes para hacer juicios:
if (list instanceFrandomAccess) {for (inti = 0; i <list.size (); i ++) {}} else {iterator <?> iterator = list.Iterable (); while (iterator.hasnext ()) {iterator.next ()}} El principio de implementación subyacente del bucle foreach es el iterador, por lo que la segunda mitad de la oración "a su vez, si se accede secuencialmente, el uso de Iterator será más eficiente" significa que las instancias de clase a las que se accede secuencialmente y usan el bucle de Foreach para atravesar.
20. Uso de bloques de código sincronizados en lugar de métodos de sincronización se ha explicado muy claramente en el artículo de bloque de método de bloqueo sincronizado en módulo múltiple. A menos que se pueda determinar que todo el método debe sincronizarse, intente usar bloques de código sincronizados para evitar sincronizar esos códigos que no necesitan sincronizarse, lo que afecta la eficiencia de la ejecución del código.
21. Declare las constantes como final estática y nombrarlas en capital para que estos contenidos se puedan colocar en el grupo constante durante la compilación, evitando el cálculo de los valores constantes generados durante el tiempo de ejecución. Además, nombrar el nombre de una constante en capital también puede facilitar la distinción entre constantes y variables
22. No cree algunos objetos no utilizados, no importe algunas clases no utilizadas
Esto no tiene sentido. Si "el valor de la variable local i no se usa" y "la importación java.util nunca se usa" aparece en el código, entonces elimine estos contenidos inútiles
23. Evite usar la reflexión durante la operación del programa. Para obtener más información, consulte la reflexión. La reflexión es una función muy poderosa proporcionada por Java a los usuarios. Las funciones poderosas a menudo significan baja eficiencia. No se recomienda utilizar el mecanismo de reflexión en el proceso de ejecutar el programa, especialmente el método Invoke del método. Si es realmente necesario, un enfoque sugerente es instanciar un objeto a través de la reflexión y ponerlo en la memoria cuando se inicia el proyecto: el usuario solo se preocupa por la velocidad de respuesta más rápida al interactuar con el compañero, y no le importa cuánto tiempo tarda el proyecto entre pares.
24. Use el grupo de conexión de la base de datos y el grupo de subprocesos, ambas piscinas, se utilizan para reutilizar objetos. El primero puede evitar la apertura y el cierre frecuentes de las conexiones, y el segundo puede evitar la creación frecuente y la destrucción de los hilos.
25. Use flujos de entrada y salida almacenados para operaciones de IO
Las transmisiones de entrada y salida de buffered, a saber, BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream, que puede mejorar en gran medida la eficiencia de IO
26. Use ArrayList para escenas con más inserción secuencial y acceso aleatorio, y use LinkedList para escenas con más eliminación de elementos e inserción intermedia.
Esto se conoce al comprender los principios de ArrayList y LinkedList
27. No dejes que hay demasiados parámetros formales en el método público
El método público es un método proporcionado al mundo exterior. Si le da a estos métodos demasiados parámetros formales, hay dos desventajas principales:
1) Violando la idea de programación orientada a objetos. Java enfatiza que todo es un objeto. Demasiados parámetros formales no están en línea con la idea de programación orientada a objetos.
2) Demasiados parámetros conducirán inevitablemente a un aumento en la probabilidad de error en la llamada de método. En cuanto a cuántos "demasiados" se refieren a, 3 o 4. Por ejemplo, usamos JDBC para escribir un método InsertStudentInfo. Hay 10 campos de información para estudiantes que se insertarán en la tabla de estudiantes. Estos 10 parámetros se pueden encapsular en una clase de entidad como parámetros formales del método de inserción.
28. Al escribir variables de cadena y constantes de cadena es igual a un truco relativamente común para escribir constantes de cadena en el frente. Si hay el siguiente código:
Cadena str = "123"; if (str.equals ("123")) {...} Se recomienda modificarlo a:
Cadena str = "123"; if ("123" .equals (str)) {...} Esto puede evitar principalmente excepciones de puntero nulo
32. No forje la transformación hacia abajo de los tipos de datos básicos más allá del alcance
33. Convierta un tipo de datos básicos en una cadena. El tipo de datos básicos.ToString () es la forma más rápida, seguida de String.ValueOf (Data), y Data + "La forma más lenta de convertir un tipo de datos básico en tres maneras. Tengo un tipo entero de datos I, que pueden usar I.ToString (), String.ValueOf (I), I +" ". ¿Cuán eficientes son los tres métodos?
publicstatic void main (string [] args) {intlooptime = 50000; Entero i = 0; LongStartTime = System.CurrentTimemillis (); for (intj = 0; j <looptime; j ++) {string str = string.valueOf (i); } System.out.println ("String.ValueOf ():" + (System.CurrentTimemillis () - Starttime) + "MS"); starttime = system.currentTimemillis (); for (intj = 0; j <looptime; j ++) {string str = i.ToString (); } System.out.println ("Integer.ToString ():" + (System.CurrentTimemillis () - Starttime) + "MS"); starttime = system.currentTimemillis (); for (intj = 0; j <looptime; j ++) {string str = i+""; } System.out.println ("i + /" /":" + (System.CurrentTimemillis () - Starttime) + "MS");}El resultado de la ejecución es:
String.ValueOf (): 11MsInteger.ToString (): 5ms + "": 25ms
Por lo tanto, cuando convierte un tipo de datos básico en cadena en el futuro, debe dar prioridad al uso del método toString (). En cuanto a por qué, es muy simple:
1. El método String.ValueOf () se llama método Integer.ToString () en la parte inferior, pero hará un juicio corto antes de llamar.
2. No hablaré sobre el método Integer.ToString (), lo llamaré directamente.
3. La capa inferior de I + "" usa StringBuilder para implementarlo. Primero use el método Agéntico para empalmarlo y luego use el método ToString () para obtener la cadena. Obviamente, es el 2 más rápido, el 1 más rápido y el 3 más lento.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.