#ifdef #ifndef в Java



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



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



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



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



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

710   7  

7 ответов:

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 не будет выводить скомпилированный код, который недоступен. Используйте конечную переменную, установленную в постоянное значение для вашего #define и нормальный if заявление #ifdef.

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

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

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

ЯЧПП является полным, соответствует, автономная, чистая реализация Java препроцессора языка Си. Он предназначен чтобы быть полезным для людей, пишущих C-стиль компиляторы на Java с использованием таких инструментов, как sablecc, antlr, JLex, чашка и так далее далее. Этот проект был использован для успешной предварительной обработки большей части исходный код библиотеки языка Си. Как версии 1.2.5, она также может предварительной обработки яблок с библиотека.

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

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

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

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

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

использовать заводской шаблон для переключения между реализациями класса?

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

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

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

Comments

    Ничего не найдено.