请考虑以下java源代码:
package com.stackoverflow;
public class CondSpeed {
private static final long COUNT = 1000000000;
private static final long OUTER_COUNT = 15;
private static long notEqOperator = 0L;
private static long notOperator = 0L;
private static long equalsFalse = 0L;
public CondSpeed() {
super();
}
public static void main(String[] args) {
for(int outCount = 0;outCount < OUTER_COUNT;outCount++){
notEqOperator += testNotEaualsOperator();
equalsFalse += testEqualFalse();
notOperator += testNotOperator();
}
long avrForNotEqOperator = (notEqOperator / OUTER_COUNT);
long avrForEqualsFalse = (equalsFalse / OUTER_COUNT);
long avrForNotOperator = (notOperator / OUTER_COUNT);
System.out.println("Avr for Not Equals Operator: "+avrForNotEqOperator);
System.out.println("Avr for Equals \"false\" Operator: "+avrForEqualsFalse);
System.out.println("Avr for Not Operator: "+avrForNotOperator);
}
private static long testEqualFalse(){
long now = System.currentTimeMillis();
for(long i = 0;i < COUNT;i++){
boolean truFalse = returnTrueOrFalse();
if(truFalse == false){
//do nothing...
}
}
return (System.currentTimeMillis() - now);
}
private static long testNotOperator(){
long now = System.currentTimeMillis();
for(long i = 0;i < COUNT;i++){
boolean truFalse = returnTrueOrFalse();
if(!truFalse){
//do nothing...
}
}
return (System.currentTimeMillis() - now);
}
private static long testNotEaualsOperator(){
long now = System.currentTimeMillis();
for(long i = 0;i < COUNT;i++){
boolean truFalse = returnTrueOrFalse();
if(truFalse != true){
//do nothing...
}
}
return (System.currentTimeMillis() - now);
}
private static boolean isFalse;
private static boolean returnTrueOrFalse(){
if(isFalse){
isFalse = false;
}
else{
isFalse = true;
}
return isFalse;
}
}
package com.stackoverflow;
public class CondSpeed {
private static final long COUNT = 1000000000;
private static final long OUTER_COUNT = 15;
private static long notEqOperator = 0L;
private static long notOperator = 0L;
private static long equalsFalse = 0L;
public CondSpeed() {
super();
}
public static void main(String[] args) {
for(int outCount = 0;outCount < OUTER_COUNT;outCount++){
notEqOperator += testNotEaualsOperator();
equalsFalse += testEqualFalse();
notOperator += testNotOperator();
}
long avrForNotEqOperator = (notEqOperator / OUTER_COUNT);
long avrForEqualsFalse = (equalsFalse / OUTER_COUNT);
long avrForNotOperator = (notOperator / OUTER_COUNT);
System.out.println("Avr for Not Equals Operator: "+avrForNotEqOperator);
System.out.println("Avr for Equals \"false\" Operator: "+avrForEqualsFalse);
System.out.println("Avr for Not Operator: "+avrForNotOperator);
}
private static long testEqualFalse(){
long now = System.currentTimeMillis();
for(long i = 0;i < COUNT;i++){
boolean truFalse = returnTrueOrFalse();
if(truFalse == false){
//do nothing...
}
}
return (System.currentTimeMillis() - now);
}
private static long testNotOperator(){
long now = System.currentTimeMillis();
for(long i = 0;i < COUNT;i++){
boolean truFalse = returnTrueOrFalse();
if(!truFalse){
//do nothing...
}
}
return (System.currentTimeMillis() - now);
}
private static long testNotEaualsOperator(){
long now = System.currentTimeMillis();
for(long i = 0;i < COUNT;i++){
boolean truFalse = returnTrueOrFalse();
if(truFalse != true){
//do nothing...
}
}
return (System.currentTimeMillis() - now);
}
private static boolean isFalse;
private static boolean returnTrueOrFalse(){
if(isFalse){
isFalse = false;
}
else{
isFalse = true;
}
return isFalse;
}
}
正如您所看到的,这是针对3个版本 if(false) 条件的测试。
---结果Mac OS X ---
JavaVM HotSpot 1.6.0
Avr for Not Equals Operator: 1937
Avr for Equals“false”运算符: 1937
Avr for Not Operator: 1941
JavaVM HotSpot 1.5.0
Avr for Not Equals Operator: 5023
Avr for Equals“false”运算符: 5035
Avr for Not Operator: 5067
JavaVM HotSpot 1.4.2
Avr for Not Equals Operator: 3993
Avr for Equals“false”运算符: 4015
Avr for Not Operator: 4009
JavaVM HotSpot 1.4.0
Avr for Not Equals Operator: 3961
Avr for Equals“false”运算符: 3960
Avr for Not Operator: 3961
感谢。
答案 0 :(得分:4)
!,!=和==之间的差异看起来像随机噪音 - 你真的期望它们能够达到完全相同的毫秒数吗?
然而,使用JVM版本的改进几乎肯定是真实的,尽管它可能非常特定于特定的代码片段,这是属于复杂性阈值的一些事情,需要正确处理。甚至略有不同的东西可能不会显示相同的结果。要改进测试,请计算每次测试运行的standard deviation,看看它们是否在统计上有所不同(或者只是打印出所有10个结果并注视它们)。
答案 1 :(得分:2)
答案 2 :(得分:2)
如果JVM做得不错,它会检测到以下语句不会影响计算,并会完全优化它们。
if (truFalse != true) {
//do nothing...
}
...
if (truFalse == false) {
//do nothing...
}
...
if (!truFalse) {
//do nothing...
}
换句话说,你的基准测试可能没有测量三种情况下的任何不同。
要学习的经验教训:
最好的策略是将微优化留给编译器,并专注于使用最佳算法的“宏”问题。此外,使用执行分析器来确定值得花时间进行优化的地方。