Java中的#ifdef #ifndef
我怀疑是否有办法在Java中编译时间条件,如#ifdef #ifndef在C ++中。
我的问题是,有一个用Java编写的algorithm,我有不同的运行时间提高到该algorithm。 所以我想测量一下每次使用什么样的改进措施后我能节约多less时间。
现在我有一组布尔variables,用于决定在运行时间哪些改进应该使用哪些不是。 但即使testing这些variables也会影响总运行时间。
所以我想在编译的时候想办法决定哪些部分应该被编译和使用。
有人知道用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将不会输出无法访问的编译代码。 使用#define
的常量值和#ifdef
的常规if
语句来设置最终variables。
您可以使用javap来certificate输出类文件中不包含无法访问的代码。 例如,请考虑以下代码:
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
提供以下输出,表示只编译了两个path中的一个(而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
我认为我已经find了解决scheme,它更简单。
如果我用“final”修饰符定义布尔variables,Java编译器本身可以解决这个问题。 因为它事先知道testing这个条件的结果是什么。 例如这个代码:
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是C预处理器的完整,兼容,独立的纯Java实现。 对于使用sablecc,antlr,JLex,CUP等工具编写C风格编译器的人来说,这是有用的。 这个项目已经被用来成功预处理GNU C库的大部分源代码。 从版本1.2.5开始,它也可以预处理Apple Objective C库。
如果你真的需要条件编译,而你使用Ant ,你可能可以过滤你的代码,并在其中进行search和replace。
例如: http : //weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
以同样的方式,你可以,例如,写一个filter来取代LOG.debug(...);
与/*LOG.debug(...);*/
。 这仍然会比if (LOG.isDebugEnabled()) { ... }
东西执行得更快,更不用说在同一时间更简洁了。
如果你使用Maven ,这里描述了一个类似的特性。
使用工厂模式在类的实现之间切换?
对象创build时间现在不能成为一个问题吗? 在长时间的平均时间内,所花时间的最大组成部分应该在现在的主streamalgorithm中呢?
严格地说,你并不需要一个预处理器来完成你想要达到的目标。 最有可能的其他方式来满足您的要求比我当然提出的。
final static int appFlags = context.getApplicationInfo().flags; final static boolean isDebug = (appFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0