通常而言大家普遍的认知里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)
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";}
}

系列博客:

品味性能之道<一>:性能测试思维与误区
品味性能之道<二>:性能工程师可以具备的专业素养
品味性能之道<三>:方法论
品味性能之道<四>:管理重于技术
品味性能之道<五>:SQL分析工具
品味性能之道<六>:图形化SQL分析工具
品味性能之道<七>:索引基础
品味性能之道<八>:Loadrunner关联技巧与字符处理
品味性能之道<九>:利用Loadrunner编写socket性能测试脚本简述
品味性能之道<十>:Oracle Hint
品味性能之道<十一>:JAVA中switch和if性能比较
深入理解Loadrunner中的Browser Emulation
使用Loadrunner对IBM MQ进行性能测试
怎么做性能测试--响应时间

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

品味性能之道十一:JAVA中switch和if性能比较相关推荐

  1. 在Java中使用instanceof的性能影响

    本文翻译自:The performance impact of using instanceof in Java I am working on an application and one desi ...

  2. Java中switch都可以支持哪些数据类型

    Java中switch都可以支持哪些数据类型 在JDK1.5之前,switch循环只支持byte short char int四种数据类型. JDK1.5 在switch循环中增加了枚举类与byte ...

  3. java jvm调优_(第2部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    java jvm调优 这是以前的文章(第3部分,共1部分)的继续:有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的提要 . 事不宜迟,让我们开始使用我们的 ...

  4. java jvm调优_(第1部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    java jvm调优 我已经花了几个月的时间考虑审查有关性能调优,JVM,Java中的GC,Mechanical Sympathy等主题的文章和视频的缓存,并最终花了点时间–也许这就是重点我什么时候才 ...

  5. (第1部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    我已经花了几个月的时间考虑审查有关性能调优,JVM,Java中的GC,Mechanical Sympathy等主题的文章和视频的缓存,并最终花了点时间–也许这就是重点我什么时候需要做我的智力进步! 感 ...

  6. (第2部分,共3部分):有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的摘要...

    这是以前的文章(第3部分,共1部分)的继续:有关性能调优,Java中的JVM,GC,Mechanical Sympathy等的文章和视频的提要 . 事不宜迟,让我们开始使用我们的下一组博客和视频,印章 ...

  7. Java 中 switch 的用法

    Java 中 switch 的用法 1.switch 中的表达式的数据的数据类型为 byte, short, int, char, String(jdk > 1.7支持 String 类型) 2 ...

  8. java中的native方法性能到底怎么样?

    前言 java中的native方法性能到底怎么样? 第一次写博客,如果写的不好,望见谅,烦请指出问题,虚心学习 先说结论,native 方法性能不如java方法 一.native方法? 主要是java ...

  9. java中switch用法举例范围_Java中Switch用法代码示例

    一.java当中的switch与C#相比有以下区别 注:在java中switch后的表达式的类型只能为以下几种:byte.short.char.int(在Java1.6中是这样), 在java1.7后 ...

最新文章

  1. android php mysql json 查询_使用json从PHP-MySql服务器到Android获取图像
  2. 矩形面积交(蓝桥杯)
  3. android之monkey测试
  4. iOS 一种很方便的构造TarBar
  5. DBeaver mysql驱动连接问题
  6. 常用术语中英简繁对照- -
  7. 产品读书《缔造企鹅:产品经理是这样炼成的》
  8. 经纬度转小数格式 java_怎么把经纬度转成小数
  9. 常用统计算法JAVA实现 - 峰度(07)
  10. 初学vue,模仿个静态网站
  11. easyui教程 php,Easyui 创建子网格_EasyUI 教程
  12. 如何编辑图片上的文字?在线图片去字工具怎样使用?
  13. 开源资产扫描系统-ARL资产灯塔系统
  14. Spring Data JPA方法定义规范
  15. 这些响应式网页测试工具确保你的设计万无一失
  16. openpbs环境下GPU版NAMD的作业提交问题
  17. spring 框架(二)
  18. 解决WPS字体的问题
  19. SLAM基础 —— 视觉与IMU融合(VIO基础理论)
  20. HTML+CSS实现商品介绍模考(以Apple14为案例)

热门文章

  1. zigbee上位机通过vs2019的mfc实现
  2. 树莓派和微信和服务器,用树莓派搭建微信公共平台
  3. 让apache解析html里的php代码,让Apache解析html文件中的php语句
  4. 地图自定义图标_如何在H5里添加地图导航?这份教程请收藏!
  5. nodejs核心模块fs删除文件_用 NodeJS 重命名系统文件
  6. mysql8添加索引_MySQL8.0新特性-新的索引方式
  7. XP的用户账户使用了HTML界面,XP系统点击用户账户显示参数无效怎么办?WinXp下点击用户账户提示参数无效解决方案...
  8. MySql数据类型介绍
  9. jq 比较两个时间是否在同一天_jq: 属性-class
  10. 有oracle操作系统,Oracle操作系统认证方式