# ifdef # ifndef en Java
je doute qu'il y ait un moyen de rendre les conditions de compilation en Java comme #ifdef #ifndef en C++.
Mon problème, c'est qu'un algorithme écrit en Java, et j'ai différents temps d'exécution améliore à cet 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 sont utilisées pour décider pendant le temps de fonctionnement quelle amélioration devrait être utilisée et laquelle Non. Mais même tester ces variables influence la durée totale de fonctionnement.
donc je veux trouver un moyen de décider pendant le temps de compilation quelles parties du programme doivent être compilées et utilisées.
quelqu'un connaît un moyen de le faire en Java. Ou peut-être quelqu'un sait qu'il n'existe aucun moyen (il serait également utile).
7 réponses
private static final boolean enableFast = false;
// ...
if (enableFast) {
// This is removed at compile time
}
Les conditions comme celles indiquées ci-dessus sont évaluées au moment de la compilation. Si à la place vous utilisez ce
private static final boolean enableFast = "true".equals(System.getProperty("fast"));
alors toutes les conditions dépendant d'enablfast seront évaluées par le compilateur JIT. Les frais généraux pour cela sont négligeables.
javac ne produira pas de code compilé inaccessible. Utilisez une variable finale définie à une valeur constante pour votre #define
et une normale if
déclaration pour le #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érons le code suivant:
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
donne la sortie suivante, indiquant qu'un seul des deux chemins était compilé dans (et la déclaration if ne l'était pas):
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
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 " Java compiler lui-même résout le problème. Parce qu'il sait à l'avance quel serait le résultat de tester 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++;
}
passe environ 3 secondes sur mon ordinateur.
Et celui-ci
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++;
}
passe environ 1 seconde. Le même temps, cette le code prend
int j=0;
for(int i=0;i<1000000000;i++){
j++;
}
ne L'a jamais utilisé, mais cela existe
JCPP est un complet, conforme, mise en œuvre autonome, en Java pur le préprocesseur C. Il est destiné pour être utile aux gens qui écrivent en style C compilateurs en Java utilisant des outils comme sablecc, antlr, JLex, CUP et so de suite. Ce projet a été utilisé pour réussir à pré-traiter la plupart des le code source de la bibliothèque C de GNU. Comme de la version 1.2.5, il peut aussi préprocesseur de la pomme objectif C bibliothèque.
si vous avez vraiment besoin de compilation conditionnelle et que vous utilisez Ant , vous pourriez être en mesure de filtrer votre code et faire une recherche-et-remplacer dans celui-ci.
par exemple: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
de la même manière que vous pouvez, par exemple, écrire un filtre pour remplacer LOG.debug(...);
par /*LOG.debug(...);*/
. Cela s'exécuterait encore plus vite que le truc if (LOG.isDebugEnabled()) { ... }
, sans parler d'être plus concis dans le même temps.
si vous utilisez Maven , il y a une caractéristique similaire décrite ici .
utiliser le modèle D'usine pour passer d'une implémentation d'une classe à une autre?
le temps de création de l'objet ne peut pas être un problème maintenant, n'est-ce pas? Quand on fait la moyenne sur une longue période de temps, la plus grande composante du temps devrait être dans l'algorithme principal maintenant ne serait-ce pas?
Strictement parlant, vous n'avez pas vraiment besoin d'un préprocesseur pour faire ce que vous cherchez à atteindre. Il y a très probablement d'autres façons de répondre à votre exigence que celle que je ont proposé bien sûr.
final static int appFlags = context.getApplicationInfo().flags;
final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0