品味性能之道<十一>:JAVA中switch和if性能比较

通常而言大家普遍的认知里switch case的效率高于if else。根据我的理解而言switch的查找类似于二叉树,if则是线性查找。按照此逻辑推理对于对比条件数目大于3时switch更优,并且对比条件数目越多时switch的优势越为明显。

 

一、测试目的

最近与开发同学对于前面提到的性能问题,有着各自不同的见解,为证明我的观点,现设计如下测试场景验证

PS:一个方法里多达65个if else


 

二、测试策略
利用Junit4执行本次测试,分别设计50个、70个、100个条件式测试,每轮测试分别执行1千万、2千万、3千万、4千万、5千万和6千万次,为了力求让每轮测试不受外部因素干扰每轮测试执行10次收集信息分析。
为了让java在纯净的环境中运行。同时关闭了QQ、360、chrome等应用软件。 


三、测试环境
  • Java 版本信息
Java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
Junit4
  • JVM配置信息
--launcher.XXMaxPermSize
256m
-Dosgi.requiredJavaVersion=1.6
-Xms512m
-Xmx1024m
  • 系统信息
Windows7 旗舰版
64位操作系统
  • 设备信息
处理器:Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz 2.20 GHz
安装内存(RAM):4.00GB (3.90 GB 可用)
因此次不涉及硬盘读写,故不记录硬盘信息


四、测试脚本
        因篇幅所限,测试脚本略有缩减。
 1  import java.util.Calendar;
 2  import java.util.GregorianCalendar;
 3  import java.util.Random;
 4  import org.junit.After;
 5  import org.junit.Before;
 6  import org.junit.Test;
 7  public  class ServerServiceTest {
 8  Calendar calender_begin, calender_end;
 9  Long time_begin, time_end;  // 记录测试开始时间,结束时间
10   int flagNumber = 1000000; //  迭代数
11  Random r =  new Random();
12   int i =  new Random().nextInt(100); // 生成随机种子
13  @Before
14   public  void setUp()  throws Exception {
15   calender_begin =  new GregorianCalendar();
16   time_begin = calender_begin.getTimeInMillis();
17  }
18  @After
19   public  void tearDown()  throws Exception {
20   calender_end =  new GregorianCalendar();
21   time_end = calender_end.getTimeInMillis();
22   System.out.println(time_end - time_begin);
23  }
24  @Test
25   public  void ifTest() {
26    for ( int temp = 0; temp < flagNumber; temp++) {
27    i = r.nextInt(100);
28     if (i == 0) {
29    }  else  if (i == 1) {
30    }  else  if (i == 2) {
31    }  else  if (i == 3) {
32    }  else  if (i == 4) {
33    }  else  if (i == 5) {
34    }  else  if (i == 6) {
35    }  else  if (i == 7) {
36    }  else  if (i == 8) {
37    }  else  if (i == 9) {
38    }  else  if (i == 10) {
39    } 
40   }
41  }
42  @Test
43   public  void switchTest()  throws InterruptedException {
44    for ( int temp = 0; temp < flagNumber; temp++) {
45    i = r.nextInt(100);
46     switch (i) {
47     case 0:
48      break;
49     case 1:
50      break;
51     case 2:
52      break;
53     case 3:
54      break;
55     case 4:
56      break;
57     case 5:
58      break;
59     default:
60      break;
61    }
62   }
63  }
64 }
View Code 

五、测试结果
        以下是收集的测试数据, 时间单位毫秒(ms)。其实这种数据看起来很难看出问题所在。
        
条件式测试数迭代数 1
(ms)
2345678910avgmaxmin
1006千万if469466474455477478466460464483469483455
switch443443441438443437441442439438441443437
5千万if399420394403408402403393410430406430393
switch367374370366374382381376373397376397366
4千万if344325326359320325324319319328329359319
switch302305300315302302298318297300304318297
3千万if255249240248249247250256251246249256240
switch228232227231230229227231228231229232227
2千万if211177183182181172174170175178180211170
switch165149155152154155155166151158156166149
1千万if179174176176169177176191173183177191169
switch152156167161158151161161159161159167151
706千万if424416440437427419417411416429424440411
switch389395387388388392397391392393391397387
5千万if368366352354351352350362355361357368350
switch327327326324328327324323330325326330323
4千万if321300295293284283281335276281295335276
switch259262260262259261259268260267262268259
3千万if219229226217220226215223217226222229215
switch199197203199199199197200200197199203197
2千万if149158152155177159159158161150158177149
switch136136132134145133133132136133135145132
1千万if86838781908877839585869577
switch65676767687167686868687165
506千万if374361363363362364376366372373367376361
switch347343341341338362340343343343344362338
5千万if324312306306341312312299307307313341299
switch289287285283291288290288290281287291281
4千万if287247251252265247248256252256256287247
switch239237236229243230235232228228234243228
3千万if193196195197203198201188200204198204188
switch184178181175173172176184193174179193172
2千万if128129133145133139139130131143135145128
switch117118118117115120114113116118117120113
1千万if81688275766869799175769168
switch60576060596559626160606557


六、测试结果分析
        纯数据的测试结果,很难进行分析,经过整理以后如下图:
        
 
         if-100为if执行100条件式测试数,switch-100为switch执行100条件式测试数;
        根据此图表结果,大家已经可能很清晰的看出 IfSwtich的性能对比结果了。但是如此细微的性能差异,实现了业务就行了,何必关注这种费心又麻烦的事呢?
        哈哈哈,性能测试更多时候,也是沟通问题,更是行政问题。

 

 
七、总结
        这次验证过程,其实就是一次简单的性能测试过程,也就是——需求挖掘->明确目的->设计策略->准备环境->脚本编写->收集数据->结果分析->测试报告。此处略去的报告内容,因为不需要什么报告了。哈哈哈!(大家懂的)
        就大量条件式的业务场景而言,除了利用switch以外,其实还可以用到枚举(enum)作为条件式,抽象每个判断式导向为函数式(function)。可能哪天我心情好会把利用enum优化的代码给放出来。
 

2015-8-23 15:17:18 跟新
策略模式+接口注入,写的是伪代码没有严格的语法规范,大家凑合着看。
interface Service{
	
	public void execute();

	public <T> T eval();
}


public class Strategy{

	private static Concrunthashmap<String,function> content = new Concrunthashmap<String,function>();

	public void register(String name,Clas<T> xxx){
		if(!content.has(name)){
			content.put(xxx);//这里隐去了反射生成对象的过程
		}
	}

	public void execute(String name){
		content.get(name).execute();
	}

	public void eval(String name){
		content.get(name).eval();
	}
}

class HelloServiceImpl implements Service{

	public void execute(){
		print "hello world";
	}

	public String eval(){
		return "hello world";
	}
}

class HiServiceImpl implements Service{

	public void execute(){
		print "hi world";
	}

	public String eval(){
		return "hi world";
	}
}

 

 

转载于:https://www.cnblogs.com/snifferhu/p/3500864.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值