H-M*_*an2 5 java oop performance if-statement
我正在扩展和改进Java应用程序,该应用程序也使用小型DSL进行长时间运行的搜索(详细地说,它用于模型查找,是的,它通常是NP-Complete).
在此搜索过程中,我想在控制台上显示一个小进度条.由于DSL的通用结构,我无法计算整体搜索空间大小.因此我只能输出第一个"回溯"语句的进度.
现在问题是:我可以为每个回溯语句使用一个标志来指示此语句应该报告进度.在评估语句时,我可以使用if语句检查标志:
public class EvalStatement {
boolean reportProgress;
public EvalStatement(boolean report) {
reportProgress = report;
}
public void evaluate() {
int progress = 0;
while(someCondition) {
// do something
// maybe call other statement (tree structure)
if (reportProgress) {
// This is only executed by the root node, i. e.,
// the condition is only true for about 30 times whereas
// it is false millions or billions of times
++progress;
reportProgress(progress);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我也可以使用两个不同的类:
这看起来像这样:
public class EvalStatement {
private ProgressWriter out;
public EvalStatement(boolean report) {
if (report)
out = new ProgressWriterOut();
else
out = ProgressWriter.instance;
}
public void evaluate() {
while(someCondition) {
// do something
// maybe call other statement (tree structure)
out.reportProgress(progress);
}
}
}
public class ProgressWriter {
public static ProgressWriter instance = new ProgressWriter();
public void reportProgress(int progress) {}
}
public class ProgressWriterOut extends ProgressWriter {
int progress = 0;
public void reportProgress(int progress) {
// This is only executed by the root node, i. e.,
// the condition is only true for about 30 times whereas
// it is false millions or billions of times
++progress;
// Put progress anywhere, e. g.,
System.out.print('#');
}
}
Run Code Online (Sandbox Code Playgroud)
现在真正的问题是:
我知道Log4J建议在日志调用周围加一个if语句,但我认为主要原因是构造参数,特别是字符串.我只有原始类型.
编辑:我澄清了一点代码(经常被称为...单例的用法在这里无关紧要).
此外,我进行了两次长期的搜索运行,其中if-statement和操作调用分别在一台机器上执行了1.840.306.311次:
if
版本耗时10h 6min 13sek(每秒50.343次点击)or
版本耗时10h 9min 15sek(每秒50.595次点击)我想说,这并没有给出真正的答案,因为0.5%的差异在于测量公差.
我的结论是:他们的行为或多或少都是一样的,但是从凯恩的答案中猜测,最重要的方法可能在长期内更快.
我认为这是过度优化的教科书定义.您甚至不确定自己是否存在性能问题.除非您在该部分进行了数百万次呼叫,否则如果您对其进行了分析,它甚至都不会显示在您的热点报告中.如果语句和方法调用大约需要纳秒才能执行.因此,为了使它们之间存在差异,您最多只能节省1-10ns.对于那甚至被人类认为是慢的,它需要在100毫秒的量级,并且如果他们的用户甚至像主动点击等那样关注,如果他们正在观看进度条他们不是甚至会注意到它.
假设我们想看看是否增加了1秒的额外时间,你发现其中一个可以节省10秒(这可能节省了1-4ns).这意味着你需要将该部分称为100,000,000次以节省1s.我可以保证,如果你有1亿个电话,你会发现10个其他区域比那里的if或polymorphism更昂贵.看起来有点愚蠢地辩论10ns的优点,你可能会节省1s不是吗?
我会更关心你使用单身而不是表现.
真正回答这个问题的唯一方法是在正常情况下尝试两者并分析代码。有很多变数。
也就是说,如果我必须猜测的话,我会这么说:
一般来说,if 语句编译为比方法调用更少的字节码,但通过 JIT 编译器优化,您的方法调用可能会被内联,这不是字节码。此外,通过 if 语句的分支预测,成本是最小的。
同样,一般来说,如果您应该在每次运行循环时进行报告,那么使用接口会比测试更快。从长远来看,加载两个类、测试一次并实例化一个类的成本将低于运行特定测试十亿次。从长远来看。
同样,更好的方法是在现实世界的示例中以两种方式分析代码,甚至可能报告您的结果。但是,我很难看到这是您的应用程序的性能瓶颈...如果速度是一个问题,您的时间可能最好花在其他地方进行优化。