Java 中的 #ifdef #ifndef
我怀疑是否有一种方法可以在 Java 中创建像 C++ 中的 #ifdef #ifndef 那样的编译时条件。
我的问题是有一个用 Java 编写的算法,并且我对该算法有不同的运行时间改进。所以我想衡量一下每次使用改进后我节省了多少时间。
现在我有一组布尔变量,用于在运行时决定应该使用哪些改进,哪些不应该使用。但即使测试这些变量也会影响总运行时间。
所以我想找到一种方法来决定在编译期间应该编译和使用程序的哪些部分。
有人知道用 Java 实现这一点的方法吗?或者也许有人知道没有这样的方法(它也很有用)。
I doubt if there is a way to make compile-time conditions in Java like #ifdef #ifndef in C++.
My problem is that have an algorithm written in Java, and I have different running time improves to that algorithm. So I want to measure how much time I save when each improve is used.
Right now I have a set of boolean variables that are used to decide during the running time which improve should be used and which not. But even testing those variables influences the total running time.
So I want to find out a way to decide during the compilation time which parts of the program should be compiled and used.
Does someone knows a way to do it in Java. Or maybe someone knows that there is no such way (it also would be useful).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
像上面所示的条件是在编译时评估的。如果您使用此选项,
则任何依赖于enableFast的条件都将由JIT编译器进行评估。这样做的开销可以忽略不计。
Conditionals like that shown above are evaluated at compile time. If instead you use this
Then any conditions dependent on enableFast will be evaluated by the JIT compiler. The overhead for this is negligible.
javac 不会输出无法访问的编译代码。对
#define
使用设置为常量值的最终变量,对#ifdef
使用普通的if
语句。您可以使用 javap 来证明无法访问的代码不包含在输出类文件中。例如,考虑以下代码:
javap -c Test
给出以下输出,表明仅编译了两个路径之一(而 if 语句未编译):javac will not output compiled code that is unreachable. Use a final variable set to a constant value for your
#define
and a normalif
statement for the#ifdef
.You can use javap to prove that the unreachable code isn't included in the output class file. For example, consider the following code:
javap -c Test
gives the following output, indicating that only one of the two paths was compiled in (and the if statement wasn't):我想我已经找到了解决方案,它更简单。
如果我使用“final”修饰符定义布尔变量,Java 编译器本身就可以解决问题。因为它预先知道测试此条件会产生什么结果。
例如这段代码:
在我的计算机上运行大约 3 秒。
这个
运行时间大约为 1 秒。此代码花费的时间相同
I think that I've found the solution, It's much simpler.
If I define the boolean variables with "final" modifier Java compiler itself solves the problem. Because it knows in advance what would be the result of testing this condition.
For example this code:
runs about 3 seconds on my computer.
And this one
runs about 1 second. The same time this code takes
没用过,不过这个确实存在
http://www.anarres.org/projects/jcpp/
Never used it, but this exists
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,则有一个类似的功能描述此处。
If you really need conditional compilation and you use Ant, you might be able to filter your code and do a search-and-replace in it.
For example: http://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
In the same manner you can, for example, write a filter to replace
LOG.debug(...);
with/*LOG.debug(...);*/
. This would still execute faster thanif (LOG.isDebugEnabled()) { ... }
stuff, not to mention being more concise at the same time.If you use Maven, there is a similar feature described here.
如果您使用 IntelliJ,有一个名为 Manifold 的插件,它与许多其他功能一起允许在 Java 中使用
#ifdef
和#define
。插件网址:
https://manifold.systems/
预处理器信息:
https://github.com/manifold- Systems/manifold/tree/master/manifold-deps-parent/manifold-preprocessor
PS:我不隶属于他们,我们只是碰巧使用它,它在没有工作流程的情况下有很大帮助(这可能不是)典型的 Java 开发)
If you use IntelliJ there is a plugin called Manifold, that - along with many other features - allows one to use
#ifdef
and#define
in Java.Plugin url:
https://manifold.systems/
Preprocessor information:
https://github.com/manifold-systems/manifold/tree/master/manifold-deps-parent/manifold-preprocessor
PS: I am not affiliated with them, we just happen to use it, and it helps a lot with out workflow (which is likely NOT typical for Java development)
使用工厂模式在类的实现之间切换?
现在对象创建时间不再是问题了,不是吗?当在较长的运行时间段内进行平均时,所花费的时间的最大部分现在应该是在主算法上,不是吗?
严格来说,您实际上并不需要预处理器来完成您想要实现的目标。当然,除了我提出的方法之外,很可能还有其他方法可以满足您的要求。
Use the Factory Pattern to switch between implementations of a class?
The object creation time can't be a concern now could it? When averaged over a long running time period, the biggest component of time spent should be in the main algorithm now wouldn't it?
Strictly speaking, you don't really need a preprocessor to do what you seek to achieve. There are most probably other ways of meeting your requirement than the one I have proposed of course.