java - sirve - Solucionar problemas de compilación lenta
programacion android pdf 2018 (3)
¿Qué debo hacer para investigar y solucionar un problema de compilación lenta ?
Mi proyecto tiene alrededor de 100 clases y toma más de 45 segundos para compilar, lo que me parece muy lento. Como referencia, tengo otro proyecto con 50 clases que se compila en 3 segundos.
PD:
- Uso maven como herramienta de construcción. Se tarda unos 50 segundos en compilar (
mvn clean compile
), de los cuales 45 segundos se pasan ejecutando javac (confirmado ejecutando con la opción-X
). - aumentar la cantidad de memoria no ayudó (
-Xms500m
) - Puedo dar más información sobre mi proyecto, pero es bastante estándar, así que no estoy seguro de qué información es relevante.
ACTUALIZAR
Gracias a la idea de Tagir, he logrado encontrar a uno de los culpables. Esta clase agrega 20 segundos al tiempo de compilación:
import org.jooq.DSLContext;
import org.jooq.Field;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.round;
import static org.jooq.impl.DSL.sum;
class Test {
static Object fast(DSLContext sql) {
Field<Double> a = field("a").cast(Double.class);
return sql.select()
.having(round(sum(a).cast(Double.class), 2).ne(0d));
}
static Object slow(DSLContext sql) {
return sql.select()
.having(round(sum(field("a").cast(Double.class)).cast(Double.class), 2).ne(0d));
}
}
Si el método slow
está comentado, el tiempo de compilación vuelve a la normalidad.
Resolución de problemas - enfoque general
Puede comenzar por recrear un proyecto vacío y agregar paquetes uno por uno hasta que el tiempo de compilación se vea afectado, lo que debería ayudarlo a identificar el paquete que está causando el problema.
Luego puede eliminar todas las clases en el paquete y agregarlas una por una, lo que le ayudará a encontrar las clases que causan el problema.
Luego, puede eliminar todos los métodos de cada una de esas clases y agregarlos de nuevo uno por uno hasta que vea que aumenta el tiempo de compilación (puede ahorrar tiempo al solo compilar esa clase ).
Causa especifica
En este caso, parece que la causa raíz es un error en javac, así que presenté un informe de error que se ha marcado como un duplicado de "JEP 215: Atribución en niveles para javac" con un objetivo que se debe corregir en Java 9.
Mientras tanto, la solución es introducir variables locales cuando hay llamadas de métodos genéricos anidados que usan inferencia de tipo genérico, pero desafortunadamente eso no siempre funciona ...
Hubo múltiples discusiones relacionadas con esto. Agregando estas referencias en caso de que alguien más tropiece con esta publicación.
Discusión inicial:
- https://groups.google.com/forum/#!topic/jooq-user/grv6Wu_sFtA
- Compilación lenta con jOOQ 3.6+, SQL plano y el compilador javac
En mi caso, esencialmente traté de usar el código generado automáticamente tanto como sea posible. Alternativamente, puedes probar la sugerencia que menciona Lukas en esta publicación de enlazada anteriormente.
Una característica no tan conocida de Java 8 es la Inferencia de tipo de objetivo generalizada .
Si bien permite escribir código más claro, esto requiere más trabajo para Javac
. A veces esto resulta en una complejidad exponencial del problema de inferencia de tipo. Este es un problema conocido, pero desafortunadamente aún no se ha resuelto, consulte JDK-8055984 , JDK-8067767 .
La solución es compilar en el nivel de compatibilidad de Java 7: javac -source 7
, o simplemente para usar construcciones más simples.