#ifdef #ifndef en Java

Je doute qu’il y ait un moyen de créer des conditions de compilation en Java comme #ifdef #ifndef en C ++.

Mon problème est que si vous avez un algorithme écrit en Java et que le temps d’exécution est différent de celui de l’algorithme. Je veux donc mesurer combien de temps j’économise lorsque chaque amélioration est utilisée.

En ce moment, j’ai un ensemble de variables booléennes qui servent à décider pendant le temps d’exécution quelles améliorations doivent être utilisées et lesquelles ne le sont pas. Mais même tester ces variables influe sur le temps total d’exécution.

Je veux donc trouver un moyen de décider, pendant la compilation, quelles parties du programme doivent être compilées et utilisées.

Est-ce que quelqu’un sait comment le faire en Java? Ou peut-être que quelqu’un sait qu’il n’y a pas une telle façon (ce serait aussi utile).

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

Les conditions telles que celles présentées ci-dessus sont évaluées au moment de la compilation. Si à la place vous utilisez ceci

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

Toutes les conditions dépendant de enableFast seront alors évaluées par le compilateur JIT. La surcharge pour cela est négligeable.

javac n’émettra pas de code compilé inaccessible. Utilisez une variable finale définie sur une valeur constante pour votre #define et une instruction if normale pour la #ifdef .

Vous pouvez utiliser javap pour prouver que le code inaccessible n’est pas inclus dans le fichier de classe de sortie. Par exemple, considérez le code suivant:

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

javap -c Test donne la sortie suivante, indiquant qu’un seul des deux chemins a été compilé (et que l’instruction if ne l’était pas):

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

Je pense que j’ai trouvé la solution, c’est beaucoup plus simple.
Si je définis les variables booléennes avec le modificateur “final”, le compilateur Java lui-même résout le problème. Parce qu’il sait à l’avance ce qui résulterait du test de cette condition. Par exemple ce code:

  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++; } 

fonctionne environ 3 secondes sur mon ordinateur.
Et celui-là

  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++; } 

fonctionne environ 1 seconde. En même temps, ce code prend

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

Je ne l’ai jamais utilisé, mais cela existe

JCPP est une implémentation Java pure, complète, conforme, autonome du préprocesseur C. Il est destiné à être utilisé par les personnes qui écrivent des compilateurs de style C en Java en utilisant des outils tels que sablecc, antlr, JLex, CUP, etc. Ce projet a été utilisé pour prétraiter avec succès une grande partie du code source de la bibliothèque GNU C. A partir de la version 1.2.5, il est également possible de prétraiter la bibliothèque Apple Objective C.

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

Si vous avez vraiment besoin d’une compilation conditionnelle et que vous utilisez Ant , vous pourrez peut-être filtrer votre code et y effectuer une recherche et un remplacement.

Par exemple: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html

De la même manière, vous pouvez, par exemple, écrire un filtre pour remplacer LOG.debug(...); avec /*LOG.debug(...);*/ . Cela s’exécuterait toujours plus vite que if (LOG.isDebugEnabled()) { ... } , sans parler d’être plus concis en même temps.

Si vous utilisez Maven , il existe une fonctionnalité similaire décrite ici .

Utilisez le motif d’usine pour basculer entre les implémentations d’une classe?

Le temps de création de l’object ne peut plus être un problème maintenant, n’est-ce pas? En moyenne sur une longue période de temps, la plus grande partie du temps passé devrait être dans l’algorithme principal, n’est-ce pas?

Ssortingctement parlant, vous n’avez pas vraiment besoin d’un préprocesseur pour faire ce que vous cherchez à atteindre. Il y a probablement d’autres moyens de répondre à vos besoins que celui que j’ai proposé bien sûr.

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