通常而言大家普遍的认知里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. CentsOS6 Tomcat7 报javax.management.InstanceNotFoundException 解决办法

    警告: Failed to unregister MBean with name [Catalina:j2eeType=Servlet,name=UploadServlet,WebModule=//l ...

  2. win10 时间很烦

    1.刷2次策略.2.打开控制面板-管理工具-服务里,有个windows time的服务,应该是正在运行,手动(触发),右键停止.3.win+r,regedit,打开注册表,找到HKEY_LOCAL_M ...

  3. JS----click3种方法

    js最常用的click事件3种方法 1.onclick=name() <!DOCTYPE html> <html leng="en"> <head&g ...

  4. jvm中堆和栈的区别

    1.前言.    其实jvm能优化的空间不多,最主要的是使用的共享内存不要超过默认的2g或者自己调的参数.但了解一下还是有点意思的,建议面试时还是要看,别学笔者裸奔. 2.区别.   网上说是有5点区 ...

  5. 申请ssl证书报提示caa提示

    申请ssl证书报下面提示caa提示,这和dns有关,换一组dns重新申请  send challenge err[acme error 'urn:acme:error:connection': DNS ...

  6. day26 面向对象的常用方法 和 元类的使用

    1. 面向对象中的常用方法 ***** isinstance() # 判断某个对象是不是某个类的实例 # 判断stu对象是不是Student类的实例 是不是子类 issubclass() class ...

  7. day11 闭包函数和装饰器

    1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...

  8. openvpn 使用账户密码认证

    OpenVPN使用user/passwd完成验证登录 OpenVPN使用user/passwd完成验证登录1,为什么要使用user/passwd?比常规openvpn管理方便,删除用户只需要在pwd. ...

  9. 最长公共子序列hdu1503

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503 题意:给你两个字符串,把这两个字符串合并,使合并之后的字符串最短,并且合并之后的字符之间的相对位 ...

  10. Codeforces Round #450 (Div. 2)

    Codeforces Round #450 (Div. 2) http://codeforces.com/contest/900 A #include<bits/stdc++.h> usi ...