通常而言大家普遍的认知里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; //记录测试开始时间,结束时间
  int flagNumber = 1000000;// 迭代数
  Random r = new Random();
  int i = new Random().nextInt(100);//生成随机种子
  @Before
  public void setUp() throws Exception {
   calender_begin = new GregorianCalendar();
   time_begin = calender_begin.getTimeInMillis();
  }
  @After
  public void tearDown() throws Exception {
   calender_end = new GregorianCalendar();
   time_end = calender_end.getTimeInMillis();
   System.out.println(time_end - time_begin);
  }
  @Test
  public void ifTest() {
   for (int temp = 0; temp < flagNumber; temp++) {
    i = r.nextInt(100);
    if (i == 0) {
    } else if (i == 1) {
    } else if (i == 2) {
    } else if (i == 3) {
    } else if (i == 4) {
    } else if (i == 5) {
    } else if (i == 6) {
    } else if (i == 7) {
    } else if (i == 8) {
    } else if (i == 9) {
    } else if (i == 10) {
    } 
   }
  }
  @Test
  public void switchTest() throws InterruptedException {
   for (int temp = 0; temp < flagNumber; temp++) {
    i = r.nextInt(100);
    switch (i) {
    case 0:
     break;
    case 1:
     break;
    case 2:
     break;
    case 3:
     break;
    case 4:
     break;
    case 5:
     break;
    default:
     break;
    }
   }
  }
 }

五、测试结果
        以下是收集的测试数据,时间单位毫秒(ms)。其实这种数据看起来很难看出问题所在。

条件式测试数 迭代数   1

(ms)
2 3 4 5 6 7 8 9 10 avg max min
100 6千万 if 469 466 474 455 477 478 466 460 464 483 469 483 455
switch 443 443 441 438 443 437 441 442 439 438 441 443 437
5千万 if 399 420 394 403 408 402 403 393 410 430 406 430 393
switch 367 374 370 366 374 382 381 376 373 397 376 397 366
4千万 if 344 325 326 359 320 325 324 319 319 328 329 359 319
switch 302 305 300 315 302 302 298 318 297 300 304 318 297
3千万 if 255 249 240 248 249 247 250 256 251 246 249 256 240
switch 228 232 227 231 230 229 227 231 228 231 229 232 227
2千万 if 211 177 183 182 181 172 174 170 175 178 180 211 170
switch 165 149 155 152 154 155 155 166 151 158 156 166 149
1千万 if 179 174 176 176 169 177 176 191 173 183 177 191 169
switch 152 156 167 161 158 151 161 161 159 161 159 167 151
70 6千万 if 424 416 440 437 427 419 417 411 416 429 424 440 411
switch 389 395 387 388 388 392 397 391 392 393 391 397 387
5千万 if 368 366 352 354 351 352 350 362 355 361 357 368 350
switch 327 327 326 324 328 327 324 323 330 325 326 330 323
4千万 if 321 300 295 293 284 283 281 335 276 281 295 335 276
switch 259 262 260 262 259 261 259 268 260 267 262 268 259
3千万 if 219 229 226 217 220 226 215 223 217 226 222 229 215
switch 199 197 203 199 199 199 197 200 200 197 199 203 197
2千万 if 149 158 152 155 177 159 159 158 161 150 158 177 149
switch 136 136 132 134 145 133 133 132 136 133 135 145 132
1千万 if 86 83 87 81 90 88 77 83 95 85 86 95 77
switch 65 67 67 67 68 71 67 68 68 68 68 71 65
50 6千万 if 374 361 363 363 362 364 376 366 372 373 367 376 361
switch 347 343 341 341 338 362 340 343 343 343 344 362 338
5千万 if 324 312 306 306 341 312 312 299 307 307 313 341 299
switch 289 287 285 283 291 288 290 288 290 281 287 291 281
4千万 if 287 247 251 252 265 247 248 256 252 256 256 287 247
switch 239 237 236 229 243 230 235 232 228 228 234 243 228
3千万 if 193 196 195 197 203 198 201 188 200 204 198 204 188
switch 184 178 181 175 173 172 176 184 193 174 179 193 172
2千万 if 128 129 133 145 133 139 139 130 131 143 135 145 128
switch 117 118 118 117 115 120 114 113 116 118 117 120 113
1千万 if 81 68 82 75 76 68 69 79 91 75 76 91 68
switch 60 57 60 60 59 65 59 62 61 60 60 65 57


六、测试结果分析
        纯数据的测试结果,很难进行分析,经过整理以后如下图:
        
 
        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";
}
}
 

品味性能之道<十一>:JAVA中switch和if性能比较的更多相关文章

  1. Java基础知识强化19:Java中switch分支语句

    java中switch语句: 这里expression控制表达式的数据类型只能是byte.short.char.int四种整型类型和枚举类型,不能是boolean类型: Java7(1.7)改进了sw ...

  2. java中switch、while、do...while、for

    一.Java条件语句之 switch 当需要对选项进行等值判断时,使用 switch 语句更加简洁明了.例如:根据考试的名次,给予前 4 名不同的奖品.第一名,奖励笔记本一台:第二名,奖励 IPAD  ...

  3. Java中switch对整型/字符型/字符串型具体实现细节

    转自:http://www.hollischuang.com/archives/61 Java7中switch中支持的数据类型有: byte short int char String类型 其实swi ...

  4. 浅谈Java中switch分支语句

    前言: 在程序中遇到多分支选择的时候,想必大家都喜欢用if...else if...else...语句,尤其是初学者,因为在了解switch语句之前,我也是只会用if...else语句.那么现在看完这 ...

  5. Java学习笔记十一:Java中的方法

    Java中的方法 一:什么是方法: 所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块. 学过C语言或者其他语言的应该都知道函数这个东西,在Java中,其实方法就是函数,只不过叫法不同,在 ...

  6. Java学习之道:Java中十个常见的违规编码

    近期,我给Java项目做了一次代码清理工作.经过清理后,我发现一组常见的违规代码(指不规范的代码并不表示代码错误)反复出如今代码中.因此,我把常见的这些违规编码总结成一份列表,分享给大家以帮助Java ...

  7. java中Switch的实现原理浅谈

    switch的转换和具体系统实现有关,如果分支比较少,可能会转换为跳转指令(条件跳转指令和无条件跳转指令).但如果分支比较多,使用条件跳转会进行很多次的比较运算,效率比较低,可能会使用一种更为高效的方 ...

  8. java中switch的用法以及判断的类型有哪些(String\byte\short\int\char\枚举类型)

    switch关键字对于多数java学习者来说并不陌生,由于笔试和面试经常会问到它的用法,这里做了一个简单的总结: 能用于switch判断的类型有:byte.short.int.char(JDK1.6) ...

  9. java中switch的用法

    switch关键字对于多数java学习者来说并不陌生,由于笔试和面试经常会问到它的用法,这里做了一个简单的总结: 能用于switch判断的类型有:byte.short.int.char(JDK1.6) ...

随机推荐

  1. idea gradle卡主问题

    http://services.gradle.org/distributions/  首先下载 all 版本 ,解压 ,再d盘, 并保留zip 文件  ,新建环境变量 GRADLE_HOME   指向 ...

  2. hibernate flush clear的区别

    有的时候你执行了更新什么的操作不一定能查出来:没有保存到数据库 以下的缓存是指一级缓存,即session:默认缓存是一级缓存: flush的意思就是执行sql,但是还没有commit,没有持久化:再清 ...

  3. Python gevent

    1\协程 import geventfrom gevent import monkeyimport requestsfrom bs4 import BeautifulSoupimport thread ...

  4. 三层和MVC

    一样写啊... 比如DAL层: C# code? 1 2 3 4 5 Public void Update(XXXXX.Models.News model) {         db.Entry(XX ...

  5. DIV实现垂直居中的几种方法

    说道垂直居中,我们首先想到的是vertical-align属性,但是许多时候该属性并不起作用.例如,下面的样式并不能达到内容垂直居中显示 div { width:200px; height:300px ...

  6. python模块部分 re模块 之正则表达式

    python 全栈开发 1.什么是模块 2.正则表达式 一.什么是模块? 1.模块: 是一组功能的集合 你要和一个东西打交道,但是这个东西本身和python没有关系,这个东西本身就存在, 这时,pyt ...

  7. java学习笔记整理

    java知识模块:1.基础知识,数组,字符串,正则表达式:2.类和对象,接口,继承,多态,抽象类,内部类,泛型,java常用类库.3.异常处理: 4.IO:   5.事件处理:   6.多线程:  7 ...

  8. 纯css3棋盘图案背景以及45度斜纹背景

    css代码  .stripes {     height: 250px;     width: 375px;     float: left;          margin: 10px;      ...

  9. hdu 2089 数位dp

    链接:https://vjudge.net/problem/23625/origin 中文,题目不用说了. 其实这题的数据很小,所以直接暴力也可以过,但是还是要学会数位dp,因为并不是每一题的数据都会 ...

  10. Fraction to Recurring Decimal(STRING-TYPE CONVERTION)

    QUESTION Given two integers representing the numerator and denominator of a fraction, return the fra ...