#ifdef #ifndef в Java

Я сомневаюсь, что есть способ сделать условия компиляции в Java, например #ifdef #ifndef в C ++.

Моя проблема в том, что есть алгоритм, написанный на Java, и у меня есть другое время работы, которое улучшает этот алгоритм. Поэтому я хочу определить, сколько времени я сохраняю, когда используется каждое улучшение.

Прямо сейчас у меня есть набор логических переменных, которые используются для решения в течение времени выполнения, которое должно быть улучшено, а что нет. Но даже тестирование этих переменных влияет на общее время работы.

Поэтому я хочу найти способ решить во время компиляции, какие части программы должны быть скомпилированы и использованы.

Кто-то знает способ сделать это на Java. Или, может быть, кто-то знает, что такого пути нет (это также было бы полезно).

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

Условные выражения, подобные приведенным выше, оцениваются во время компиляции. Если вместо этого вы используете это

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

Тогда любые условия, зависящие от enableFast, будут оцениваться компилятором JIT. Накладные расходы для этого незначительны.

javac не выводит скомпилированный код, неansible. Используйте конечную переменную, установленную в константное значение для #define и нормального оператора if для #ifdef .

Вы можете использовать javap, чтобы доказать, что недостижимый код не включен в файл выходного classа. Например, рассмотрим следующий код:

 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 дает следующий вывод, указывающий, что только один из двух путей был скомпилирован (и оператор if не был):

 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 

Я думаю, что нашел решение, намного проще.
Если я определяю логические переменные с «финальным» модификатором, сам компилятор Java решает проблему. Потому что он заранее знает, что было бы результатом проверки этого состояния. Например, этот код:

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

работает около 3 секунд на моем компьютере.
И этот

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

работает около 1 секунды. В то же время этот код принимает

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

Никогда не использовал его, но это существует

JCPP – это полная, совместимая, автономная, чистая реализация Java препроцессора C. Он предназначен для людей, которые пишут компиляторы C-стиля в Java, используя такие инструменты, как sablecc, antlr, JLex, CUP и т. Д. Этот проект был использован для успешной обработки большого количества исходного кода библиотеки GNU C. Начиная с версии 1.2.5, он также может предварительно обрабатывать библиотеку Apple Objective C.

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

Если вам действительно нужна условная компиляция, и вы используете Ant , вы можете фильтровать свой код и выполнять поиск и замену в нем.

Например: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html

Таким же образом вы можете, например, написать фильтр для замены LOG.debug(...); с /*LOG.debug(...);*/ . Это все равно будет выполняться быстрее, чем if (LOG.isDebugEnabled()) { ... } , не говоря уже о том, чтобы быть более кратким в одно и то же время.

Если вы используете Maven , здесь есть аналогичная функция.

Использовать Factory Pattern для переключения между реализациями classа?

Теперь время создания объекта не может быть проблемой? Когда усредняется в течение длительного периода времени, самая большая составляющая времени должна быть в основном алгоритме, не так ли?

Строго говоря, вам не нужен препроцессор, чтобы делать то, что вы добиваетесь. Есть, скорее всего, другие способы удовлетворения вашего требования, чем тот, который я предложил, конечно.

 final static int appFlags = context.getApplicationInfo().flags; final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 
Давайте будем гением компьютера.