java compilation conditional conditional-compilation

#ifdef#ifndef en Java



compilation conditional (7)

Creo que encontré la solución, es mucho más simple.
Si defino las variables booleanas con el modificador "final", el compilador Java resuelve el problema. Porque sabe de antemano cuál sería el resultado de probar esta condición. Por ejemplo, este código:

boolean flag1 = true; boolean flag2 = false; int j=0; for(int i=0;i<1000000000;i++){ if(flag1) if(flag2) j++; else j++; else if(flag2) j++; else j++; }

corre alrededor de 3 segundos en mi computadora.
Y éste

final boolean flag1 = true; final boolean flag2 = false; int j=0; for(int i=0;i<1000000000;i++){ if(flag1) if(flag2) j++; else j++; else if(flag2) j++; else j++; }

corre alrededor de 1 segundo. Al mismo tiempo que este código toma

int j=0; for(int i=0;i<1000000000;i++){ j++; }

Dudo que haya una forma de hacer condiciones de tiempo de compilación en Java como #ifdef #ifndef en C ++.

Mi problema es que tengo un algoritmo escrito en Java, y tengo diferentes tiempos de ejecución mejorados para ese algoritmo. Así que quiero medir cuánto tiempo ahorro cuando se usa cada mejora.

En este momento tengo un conjunto de variables booleanas que se utilizan para decidir durante el tiempo de ejecución que se deben usar para mejorar y cuáles no. Pero incluso la prueba de esas variables influye en el tiempo total de ejecución.

Así que quiero encontrar una manera de decidir durante el tiempo de compilación qué partes del programa deben compilarse y utilizarse.

¿Alguien sabe una forma de hacerlo en Java? O tal vez alguien sabe que no hay tal manera (también sería útil).


Nunca lo usé, pero esto existe

JCPP es una implementación Java pura, completa, autónoma e independiente del preprocesador C. Está destinado a personas que escriben compiladores de estilo C en Java utilizando herramientas como sablecc, antlr, JLex, CUP, etc. Este proyecto se ha utilizado para preprocesar con éxito gran parte del código fuente de la biblioteca C de GNU. A partir de la versión 1.2.5, también puede preprocesar la biblioteca Apple Objective C.

http://www.anarres.org/projects/jcpp/


Si realmente necesita una compilación condicional y usa Ant , podría filtrar su código y hacer una búsqueda y reemplazo en él.

Por ejemplo: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html

De la misma manera, puede, por ejemplo, escribir un filtro para reemplazar LOG.debug(...); con /*LOG.debug(...);*/ . Esto todavía se ejecutará más rápido que if (LOG.isDebugEnabled()) { ... } cosas, sin mencionar que es más conciso al mismo tiempo.

Si usa Maven , hay una característica similar que se describe here .


Use el patrón de fábrica para alternar entre implementaciones de una clase?

El tiempo de creación del objeto no puede ser una preocupación ahora, ¿o sí? Cuando se promedia durante un largo período de tiempo de ejecución, el mayor componente del tiempo debe estar en el algoritmo principal, ¿no es así?

Estrictamente hablando, realmente no necesitas un preprocesador para hacer lo que pretendes lograr. Probablemente existan otras formas de cumplir con sus requisitos que las que he propuesto por supuesto.


javac no dará salida al código compilado que es inalcanzable. Use una variable final establecida en un valor constante para su #define y una declaración if normal para #ifdef .

Puede usar javap para probar que el código inalcanzable no está incluido en el archivo de clase de salida. Por ejemplo, considere el siguiente código:

public class Test { private static final boolean debug = false; public static void main(String[] args) { if (debug) { System.out.println("debug was enabled"); } else { System.out.println("debug was not enabled"); } } }

javap -c Test da el siguiente resultado, que indica que solo se compiló una de las dos rutas (y la instrucción if no):

public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String debug was not enabled 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return


final static int appFlags = context.getApplicationInfo().flags; final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0


private static final boolean enableFast = false; // ... if (enableFast) { // This is removed at compile time }

Condicionales como el mostrado arriba son evaluados en tiempo de compilación. Si en cambio usas esto

private static final boolean enableFast = "true".equals(System.getProperty("fast"));

Entonces cualquier condición dependiente de enableFast será evaluada por el compilador JIT. La sobrecarga para esto es insignificante.