#ifdef #ifndef в Java
Я сомневаюсь, что есть способ сделать условия компиляции в Java, например #ifdef #ifndef в С++.
Моя проблема в том, что есть алгоритм, написанный на Java, и у меня есть другое время работы, которое улучшает этот алгоритм. Поэтому я хочу определить, сколько времени я сохраняю, когда используется каждое улучшение.
Прямо сейчас у меня есть набор логических переменных, которые используются для решения в течение времени выполнения, которое должно быть использовано, а что нет. Но даже тестирование этих переменных влияет на общее время работы.
Итак, я хочу узнать, как решить во время компиляции, какие части программы должны быть скомпилированы и использованы.
Кто-нибудь знает способ сделать это на Java. Или, может быть, кто-то знает, что такого пути нет (это также было бы полезно).
Ответы
Ответ 1
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. Накладные расходы для этого незначительны.
Ответ 2
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
Ответ 3
Я думаю, что нашел решение, это намного проще.
Если я определяю логические переменные с "финальным" модификатором, сам компилятор 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++;
}
Ответ 4
Никогда не использовал его, но это существует
JCPP является полным, совместимым, автономная, чистая реализация Java препроцессора C. Он предназначен для использования людьми, пишущими C-style компиляторы в Java, используя такие инструменты, как sablecc, antlr, JLex, CUP и так далее вперед. Этот проект был использован для успешного препроцесса большей части исходный код библиотеки GNU C. В виде версии 1.2.5, он также может препроцесс Apple Objective C библиотека.
http://www.anarres.org/projects/jcpp/
Ответ 5
Если вам действительно нужна условная компиляция, и вы используете Ant, вы можете фильтровать свой код и выполнять поиск и замену в нем.
Например: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
Таким же образом вы можете, например, написать фильтр, чтобы заменить LOG.debug(...);
на /*LOG.debug(...);*/
. Это все равно будет выполняться быстрее, чем if (LOG.isDebugEnabled()) { ... }
, не говоря уже о краткости в одно и то же время.
Если вы используете Maven, здесь описывается аналогичная функция .
Ответ 6
Использовать шаблон Factory для переключения между реализациями класса?
Время создания объекта не может быть проблемой сейчас? Когда усредняется в течение длительного периода времени, самая большая составляющая времени должна быть в основном алгоритме, не так ли?
Строго говоря, вам не нужен препроцессор, чтобы делать то, что вы добиваетесь. Скорее всего, есть другие способы удовлетворить ваши требования, чем тот, который я предложил, конечно.
Ответ 7
Коллектор предоставляет полностью интегрированный препроцессор Java (без этапов сборки или сгенерированного источника). Он предназначен исключительно для условной компиляции и использует директивы в стиле C.
![Manifold's Java Preprocessor]()
Ответ 8
final static int appFlags = context.getApplicationInfo().flags;
final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0