在评估某些非常特殊的条件时,我正在遇到一些非常奇怪的性能行为。
基本上,我发现我可以构建两个条件a和b是if(a)
比快10倍,if(a && b)
即使a
是始终为假,这似乎直接与事实的Java应该做的条件懒评价发生冲突。
当我有发生的情况下a
是someDate.after(startdate)
与b
是someDate.before(enddate)
即一个相当标准的范围条件- 。
在下面,我附加了用于显示此特定问题的代码。我已经在带有Java 7的Windows 7上运行了该代码,而我的一位同事已经在带有Java 6,7和8的Windows 7上运行了这些代码-都具有相同的结果。
谁能解释为什么会这样?
import java.util.Date;
public class DateWeirdness {
public static void main(String[] args) {
Date start = new Date();
System.out.println("if(a) - a always false");
System.out.println(timeBasic(2000000000, start, start.getTime() - 4000000000L));
start = new Date();
System.out.println("if(a && b) - a always false, a and b both date method");
System.out.println(timeAdv(2000000000, start, start.getTime() - 4000000000L, new Date()));
start = new Date();
System.out.println("if(a && b) - a always false, b is condition on longs not date");
System.out.println(timeAdv2(2000000000, start, start.getTime() - 4000000000L, new Date().getTime()));
start = new Date();
System.out.println("if(a) - a always false - condition on long");
System.out.println(timeBasicL(2000000000, start.getTime(), start.getTime() - 4000000000L));
start = new Date();
System.out.println("if(a && b) - a always false, a and and b both conditions on long");
System.out.println(timeAdvL(2000000000, start.getTime(), start.getTime() - 4000000000L, new Date().getTime()));
start = new Date();
System.out.println("if(a && b) - a always false, b always true");
System.out.println(timeAdv(2000000000, start, start.getTime() - 4000000000L, new Date()));
start = new Date();
System.out.println("if(a && b) - both true");
System.out.println(timeAdv(2000000000, start, start.getTime() + 1, new Date(start.getTime() + 4000000000L)));
start = new Date();
System.out.println("if(a && b) - a always true, b always false");
System.out.println(timeAdv(2000000000, start, new Date(start.getTime() + 4000000001L).getTime(), new Date(start.getTime() + 4000000000L)));
}
private static int timeBasic(int size, Date start, long l) {
long begin = System.currentTimeMillis();
int c = 0;
for (int i = 0; i < size; i++) {
Date date = new Date(l++);
if (start.before(date)) {
c++;
}
}
System.out.println(System.currentTimeMillis() - begin);
return c;
}
private static int timeAdv(int size, Date start, long l, Date end) {
long begin = System.currentTimeMillis();
int c = 0;
for (int i = 0; i < size; i++) {
Date date = new Date(l++);
if (start.before(date) && end.after(date)) {
c++;
}
}
System.out.println(System.currentTimeMillis() - begin);
return c;
}
private static int timeAdv2(int size, Date start, long l, long end) {
long begin = System.currentTimeMillis();
int c = 0;
for (int i = 0; i < size; i++) {
Date date = new Date(l++);
if (start.before(date) && end > l) {
c++;
}
}
System.out.println(System.currentTimeMillis() - begin);
return c;
}
private static int timeBasicL(int size, long start, long l) {
long begin = System.currentTimeMillis();
int c = 0;
for (int i = 0; i < size; i++) {
l++;
if (start < l) {
c++;
}
}
System.out.println(System.currentTimeMillis() - begin);
return c;
}
private static int timeAdvL(int size, long start, long l, long end) {
long begin = System.currentTimeMillis();
int c = 0;
for (int i = 0; i < size; i++) {
l++;
if (start < l && end > l) {
c++;
}
}
System.out.println(System.currentTimeMillis() - begin);
return c;
}
}
在本地运行时,我得到以下输出。有趣的测试是前三个测试。640
是执行的毫秒数if(a)
,7079
是执行的性能if(a && b)
,其中a
和b
如上所述。710
是这样做的性能if(a && b)
哪里b
是someDateAsLong < endDateAsLong
。
if(a) - a always false
640
0
if(a && b) - a always false, a and b both date method
7079
0
if(a && b) - a always false, b is condition on longs not date
710
0
if(a) - a always false - condition on long
639
0
if(a && b) - a always false, a and and b both conditions on long
708
0
if(a && b) - a always false, b always true
6873
0
if(a && b) - both true
11995
2000000000
if(a && b) - a always true, b always false
13746
0
JVM以一种start.before(date)
根本不评估的方式优化代码(我认为)。尝试将其运行-Djava.compiler=NONE
并查看结果。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句