Cómo utilizar el código Java para consultar el conjunto de datos de Yago
Optimización limitada para que el programa utilice recursos (memoria, espacio de CPU, ancho de banda de red, etc.) para permitir que el programa utilice la menor cantidad de recursos posible para completar las tareas programadas. La optimización incluye dos aspectos: reducir el código. volumen y mejora de la eficiencia de ejecución del código. Este artículo analiza principalmente cómo mejorar la eficiencia del código.
Los problemas de rendimiento del programa Java no están relacionados principalmente con el lenguaje Java. No es importante desarrollar hábitos de codificación en el programa en sí. y el uso inteligente de las clases java.lang.String y java.util.Vector puede mejorar significativamente. En términos de rendimiento del programa, analizaré los problemas en detalle
1. Intente especificar el modificador final. de la clase con el modificador final. La API central de Java permite el uso de ejemplos finales. Por ejemplo, la clase java.lang.StringString especifica final para evitar sobrescribir la longitud(). El compilador de Java encontrará todas las configuraciones finales (configuraciones de implementación específicas del compilador) en línea (configuraciones de implementación específicas del compilador), lo que puede mejorar el rendimiento en un promedio del 50 %
2. Intente reutilizar cadenas especiales como si usa cadenas. conexión, use StringBuffer en su lugar. Debido a que el sistema solo necesita dedicar algo de tiempo a la recolección de basura, tendrá un impacto en el rendimiento del programa.
3. Las variables temporales creadas se guardan en la pila, que es más rápido. Las variables, variables estáticas, variables de instancia, etc. se crean en el montón, que es más lento. Además, depende del compilador específico. /JVM. Las variables locales se pueden optimizar. Consulte "Usar la pila tanto como sea posible".
4. > La inicialización de la variable Java determina el valor: establece la variable entera nula (byte, short, int, long) configura la variable 0floatdouble configura el valor lógico 0.0 establece el punto de vista alternativo de clase falsa En particular, debes prestar atención al uso de la nueva palabra clave para. cree una cadena de constructores de imágenes. Todos los constructores se llaman automáticamente.
5. El sistema de aplicación JAVA + ORACLE envía declaraciones SQL integradas de Java. Intente utilizar el formulario de escritura para reducir la carga de análisis del analizador ORACLE.
6. La programación Java debe usarse completamente al realizar conexiones de bases de datos y operaciones de flujo de E/S, incluso si está cerrada para liberar recursos, algunas operaciones pueden causar una sobrecarga del sistema. Precaución puede provocar problemas graves
p><. p>7. Debido al propio mecanismo de GC de la JVM, los desarrolladores de programas deben considerar reducir la carga del desarrollador hasta cierto punto y omitir los peligros ocultos. La creación de objetos consume mucha memoria del sistema y provoca graves pérdidas de memoria. Las condiciones de recolección de basura de JVM son de gran importancia: la referencia de imagen JVMGC no es muy inteligente. Incluso si la imagen cumple con las condiciones de recolección de basura, se recomienda establecerla en nulo inmediatamente después de usarla.8. Cuando utilice el mecanismo de sincronización, intente utilizar la sincronización en lugar de la sincronización de bloques de código
9. Minimice el cálculo repetido de variables
Ejemplo: for(int i = 0;i < list. tamaño; i ++) {
}
Debe ser reemplazado:
for(int i = 0,int len = list.size();i < len; i ++) {
}
10. es decir, crearlo sólo cuando sea necesario
Ejemplo: String str = aaa;
if(i == 1) {
list.add(str) ;
}
Debe ser reemplazado por:
if (i == 1) {
String str = aaa; p>
list.add(str);
}
11. Utilice excepciones con precaución
Para utilizar excepciones, primero debe crear un nuevo objeto Nombre de llamada del constructor de interfaz arrojable fillInStackTrace() (Nativo) fillInStackTrace() verifica la pila y recopila información de seguimiento de llamadas Para hacer excepciones, la VM debe ajustar la pila de llamadas. La capacidad del controlador para crear un nuevo objeto se utiliza para errores. manipulación y debe controlarse utilizando
Flujo del programa
12. Para usar en un bucle:
Pruebe {
} catch() {
}
Debe colocarse en la capa exterior
13. Uso de StringBuffer:
StringBuffer representa cambiar y escribir cadenas
Tres estructuras:
StringBuffer (); //Con espacio de 16 caracteres por defecto
StringBuffer (int size); //Con espacio de caracteres de tamaño
StringBuffer (String str); caracteres+str. longitud() espacio de caracteres
Establecer la capacidad inicial a través del constructor StringBuffer mejora significativamente el rendimiento y proporciona al constructor StringBuffer(int
longitud). El antiguo StringBuffer puede mantener el número de caracteres. Utilice sureCapacity( int
minimumcapacity)Cree un objeto StringBuffer y establezca la capacidad. Primero, echaré un vistazo a la línea predeterminada de StringBuffer y encontraré una manera de mejorar el rendimiento.
StringBuffer mantiene una matriz de caracteres internamente y utiliza el constructor predeterminado para crear un objeto StringBuffer. Cuando el carácter de inicialización no está configurado, la capacidad de StringBuffer se inicializa a 16 caracteres. Cuando StringBuffer alcance la capacidad, agregue 2 veces antes de aumentar su propia capacidad y agregue 2 (2 * valor anterior + 2). Inicialice usando el valor predeterminado y luego agregue el siguiente carácter. La capacidad de 16 caracteres se incrementa en 34 (. 2*16+2). La capacidad de 34 caracteres adicionales aumenta en 70 (2*34+2). Pase lo que pase, si StringBuffer alcanza la capacidad, cree una nueva matriz de caracteres y copie todos los caracteres antiguos y nuevos. Nuevamente, es demasiado costoso. Siempre es mejor establecer un valor de capacidad inicial razonable para StringBuffer y lograr ganancias de rendimiento inmediatas.
El efecto de ajuste del proceso de inicialización de StringBuffer es siempre la mejor sugerencia para usar una capacidad adecuada. valor para inicializar StringBuffer
14. Razonable Uso de la clase Java java.util.Vector
En pocas palabras, la matriz de instancia Vectorjava.lang.Object es similar a una matriz. Se accede a través de índices enteros. Se crean objetos de tipo vectorial. El objeto se puede expandir o contraer de acuerdo con la adición o eliminación de elementos. Considere el ejemplo de agregar elementos a Vector:
Objeto obj = nuevo Objeto(). ;
Vector v = nuevo Vector(100000);
for(int I=0 ;
I<100000; I++) { v.add(0 ,obj); }
A menos que haya razones absolutamente buenas para insertar nuevos elementos delante del Vector, el rendimiento del código anterior no funcionará de forma predeterminada. La capacidad de almacenamiento inicial del Constructor Vector es de 10 elementos. Se agrega un nuevo elemento, la capacidad de almacenamiento es suficiente. Cada vez que se duplica la capacidad de almacenamiento, la clase Vector, al igual que la clase StringBuffer, cada vez que se expande la capacidad de almacenamiento, se deben copiar varios fragmentos de código en el nuevo espacio de almacenamiento. de magnitud más rápido que el ejemplo anterior: p>
Objeto obj = new Objeto();
Vector v = nuevo Vector(100000);
for(int I =0; I<100000; I++) { v.add(obj); }
Las mismas reglas se aplican a la clase Vector remove(). Ya que puede haber espacios entre los elementos de Vector, eliminando cualquiera. otro elemento excepto el elemento hará que el elemento eliminado avance. Se dice que el costo de eliminar un elemento es varias veces menor que el de eliminar el elemento.
Supongamos que quiero. para eliminar todos los elementos del Vector anterior utilizo este código:
for(int I=0; I<100000; I++)
{
v.eliminar
(0);
}
En comparación con el código anterior, el código anterior es varios órdenes de magnitud más lento:
for(int I=0; I <100000; I++ )
{
v.remove(v.size()-1);
}
Tipo de vector elimina todos los elementos:
v.removeAllElements();
Supongamos que el tipo Vector es como v y contiene la cadena Hola. Considere el siguiente código para eliminar la cadena Hola del Vector:
String s = "Hola";
int i = v.indexOf(s);
if(I != -1) v.remove( s);
Estos códigos parecen ser correctos. El fragmento de código indexOf()v realiza una búsqueda secuencial para encontrar la cadena Helloremove(s) y realiza una búsqueda secuencial:
<. p>String s = "Hola"; p>int i = v.indexOf(s);
if(I != -1) v.remove(i); p>
Para la versión que elimino() directamente, proporcione al elemento que se eliminará una posición de índice precisa para evitar una segunda actualización de búsqueda:
String s = "Hello v.remove(s)"; ;
Veré el fragmento de código de la clase Vector nuevamente:
for(int I=0; I++;I < v.length)
v contiene 100.000 elementos. El fragmento de código llama a v.size() 100.000. Aunque el tamaño es simple, todavía necesita llamar a pin. Al menos la JVM necesita configurar y borrar el entorno de pila y el código interno del bucle for para modificar el tipo de vector. de cualquier manera, al igual que el código del lado v, reescriba el código de superficie de esta forma:
int size = v.size(); for(int I=0; I++ ;I Aunque es un cambio simple, aún mejora el rendimiento. Después de todo, cada ciclo de CPU es valioso 15. Utilice el comando System.arraycopy() para copiar grandes cantidades de datos. /p> 16. Refactorización de código: mejora la legibilidad del código Ejemplo: ShopCart de clase pública { carritos de lista privada; … public void add (elemento de objeto) { if(carts == null) { carts = new ArrayList(); } crts.add(item); } eliminación de vacío público (elemento de objeto) { if (carts. contiene (artículo)) { carts.remove(artículo); } } Lista pública getCarts( ) { p> //Volver a leer la lista return Collections.unmodifiableList(carts); } //Estilos recomendados //this.getCarts().add(item); } 17. Utilice la nueva palabra clave para crear una instancia de clase
Cuando uso Diseño. Patrón, use el modo Factory para crear un objeto. Use clone() en su lugar para crear una nueva instancia del modo Factory de instancia no simple.
Implementación típica:
crédito estático público getNewCredit() {
return new Credit();
}
Mejora el código usando clonar ( ):
Crédito estático privado BaseCredit = nuevo Crédito();
Crédito público estático getNewCredit() {
devolución (Crédito) BaseCredit.clone( ) ;
}
La idea de la cara es la misma para el procesamiento de matrices
18. Multiplicación y división
Considere el código de la cara:
for (val = 0; val < 100000; val +=5) {
alterX = val * 8; myResult = val * 2;
}
Utilice la operación de desplazamiento en lugar de la operación de multiplicación para mejorar en gran medida el rendimiento:
for (val = 0; val < 100000; val += 5) {
<. p>alterX = val < < 3; myResult = val << 1;}
Modifique el código y realice la operación de multiplicación por 8, use la operación equivalente de desplazamiento 3 bits a la izquierda. Cada desplazamiento a la izquierda de 1 bit equivale a multiplicar por 2. La operación de desplazamiento a la derecha de 1 bit es mejor que la división de 2 valores. Aunque la operación de desplazamiento es más rápida, puede hacer que el código sea más difícil de entender. Se agregan algunos comentarios
19. Función de cierre de página JSP
Ver sesión de malentendido El hecho de que se crea el acceso del cliente no se crea hasta que un programa del lado del servidor llama a HttpServletRequest.getSession. (verdadero) declaración Tenga en cuenta que JSP no muestra que si cierra la sesión, el archivo JSP se compila y el servlet agrega una declaración HttpSession
session = HttpServletRequest.getSession( verdadero icono de sesión JSP); historial Dado que la sesión consume recursos de memoria y está destinada a ser utilizada, el JSP debe cerrarse
Para aquellos que necesitan realizar un seguimiento del estado de la página, cierre la creación propia para ahorrar algunos recursos y utilizarla. la directiva de página:
20. JDBC y E/S
Las aplicaciones que necesitan acceder a conjuntos de datos a gran escala deben considerar el uso de extracción de bloques. De forma predeterminada, JDBC extrae 32 filas de datos. Por ejemplo, suponiendo que quiero recorrer un conjunto de registros de 5000 filas, JDBC debe llamar a la base de datos 157 para extraer todos los bloques de datos. Si la base de datos se cambia a 512, el número de llamadas a la base de datos se reducirá en 10 <. /p>
[p][/p] 21. Uso de servlet y memoria
El desarrollador puede guardar la información del usuario en cualquier cantidad. A veces, el icono de almacenamiento no cumple con el rendimiento de recolección de basura. Los síntomas típicos incluyen la desaceleración periódica del sistema del usuario, pero se puede atribuir a cualquier componente específico. Supervise el rendimiento del espacio de almacenamiento dinámico de la JVM y el uso de la memoria.
Hay dos formas principales de resolver los problemas de memoria. el bean implementa la interfaz HttpSessionBindingListener. Debe implementar valueUnbound() para liberar explícitamente los recursos utilizados por el bean. Además, el servidor de aplicaciones debe configurar la opción de intervalo de invalidación lo antes posible. Además, setMaxInactiveInterval() llama programáticamente a setMaxInactiveInterval. (), que se puede utilizar para configurar el servlet antes de la invalidación. El contenedor permite segundos entre solicitudes del cliente
22. Uso de etiquetas de búfer
Algunos servidores de aplicaciones han agregado funciones de etiquetas de búfer para JSP. Por ejemplo, BEAWebLogic Server versión 6.0 solo admite la función Abrir
El proyecto Symphony también admite etiquetas de almacenamiento en búfer JSP, que pueden almacenar en búfer fragmentos de página y toda la página si el fragmento de destino de ejecución de la página JSP ha sido almacenado en búfer. , el código del fragmento se volverá a ejecutar con almacenamiento en búfer a nivel de página para capturar la solicitud de URL especificada y almacenar en búfer la página integrada en la cesta de compras. La función de página de inicio del directorio y del portal es particularmente adecuada para el almacenamiento en búfer a nivel de página similar a una aplicación, que puede ahorrar. resultados de ejecución de la página.
Para uso en solicitudes posteriores
23. Elija el mecanismo de referencia adecuado
Las páginas y pies de página del sistema de aplicación JSP típicos a menudo se extraen para presentar las páginas según sea necesario. Hay dos tipos principales de páginas JSP. antes del pie de página que introduce recursos externos Tipos: directiva de inclusión y operación de inclusión
Directiva de inclusión: Ejemplo <%@ include file="copyright.html"
%>Esta directiva compila y. introduce el recurso especificado con la página de directiva de inclusión antes de la compilación. Es más eficiente compilar el archivo de combinación de recursos especificado para hacer referencia a recursos externos que determinar los recursos antes de ejecutar la operación
Include: Ejemplo />Esta operación se introduce. El resultado de la ejecución de la página especificada es más flexible porque el control de salida después de la ejecución es más flexible. El contenido de referencia cambia con frecuencia o la solicitud de la página principal. no aparece en la página de referencia actual. Es más rentable utilizar la operación de inclusión > Borrar y luego permitir que el servidor de aplicaciones tenga un valor predeterminado de más de 30 minutos. El servidor de aplicaciones necesita ahorrar más memoria. El sistema es suficiente para transferir los datos de la memoria al disco. El servidor de aplicaciones se puede usar con frecuencia (el más utilizado recientemente). La calculadora salta al disco e incluso puede desechar la memoria. es costoso para sistemas de diferentes escalas y requiere limpieza llamando a HttpSession.invalidate(). HttpSession.invalidate() generalmente se llama retrocediendo la página 25. 26. Discusión sobre la eficiencia transversal de HashMap Hay dos operaciones transversales de valor de HashMapkeyvalue: Map paraMap = new HashMap(); ....... ..//Loop Set appFieldDefIds = paraMap.keySet(); for (String appFieldDefId : appFieldDefIds) { String[] valores = paraMap.get(appFieldDefId); ...... } //Segundo bucle for(Entrada de entrada : paraMap.entrySet()){ String appFieldDefId = Entry.getKey(); String [] valores = Entry.getValue(); ..... } La primera implementación tiene una eficiencia obvia y la segunda implementación Analysis Set appFieldDefIds = paraMap.keySet(); Primero obtenga keySet de HashMap Código: public Set keySet() { Set ks = keySet; return (ks ! = null ? ks : (keySet = new KeySet())); } Clase privada KeySet extiende AbstractSet { Iterador público iterador() { return newKeyIterator(); } public int size() { retorno tamaño; } público booleano contiene(Objeto o) { return contieneClave(o); } > public boolean remove(Object o) { return HashMap.this.removeEntryForKey(o) != null; } public void clear () { HashMap.this.clear(); } } De hecho, devuelve la clase privada KeySet , AbstractSet hereda la implementación de la interfaz Set Mira el bucle for/in nuevamente for(declaración: expresión_r) declaración Traducción de la fase de ejecución for(Iterator #i = (expression_r).iterator(); #i.hashNext();){ declaración = #i.next(); declaración } La declaración for para (String appFieldDefId: appFieldDefIds) llama a HashMap.keySet().iterator() llama a newKeyIterator() Iterador newKeyIterator() { devuelve nuevo KeyIterator(); } clase privada KeyIterator extiende HashIterator { público K next() { return nextEntry().getKey(); } } llamado por for El segundo bucle para (Entrada entrada: paraMap.entrySet()) utiliza la clase interna Iterator la clase privada EntryIterator extiende HashIterator Mapa público .Entry next() { return nextEntry(); } } La clave del primer ciclo, segundo ciclo HashMapEntry p> La superficie del bucle de eficiencia refleja que el segundo bucle obtiene directamente el valor del valor clave El primer bucle luego usa HashMapget (clave de objeto) para obtener el valor Ahora tome un mire HashMapget (clave de objeto) public V get(clave de objeto) { Objeto k = maskNull(clave); int hash = hash(k ); int i = indexFor(hash, table.length); //Entrada[] tabla Entrada e = tabla; mientras (verdadero) { if (e == null) return null; if (e.hash == hash && eq(k, e.key)) valor de retorno e.; e = e.next; } } De hecho , el valor Hash se usa para obtener la Entrada correspondiente para comparar. Utilice el primer bucle para ingresar HashMapEntry El segundo bucle obtiene el valor de Entrada. Obtener directamente el valor clave es más eficiente que el primer bucle. De hecho, según el concepto de Mapa, el segundo bucle debe usarse para seleccionar el valor clave.