前言我们经常在很多项目里面看到用异常来处理业务逻辑,发现不符合预期直接抛出异常,然后在最外面捕获异常统一处理,这样使用非常方便 。
但是又有很多文章写着异常处理性能,所以不建议使用异常来做流程控制 。甚至在阿里巴巴开发手册里面明确说明了,不要用来做流程控制 。
文章插图
那么问题来了:
究竟能不能用异常来做流程控制?效率低是低多少?看完这一篇文章你就知道了 。
开始测试先做最简单的测试我们循环10万次,然后栈有5层,然后输出返回结果 。
private static final int RUN_COUNT = 10 * 10000;/*** 测试异常耗时* 输出异常堆栈&信息*/@Testpublic void printStack() {long start1 = System.currentTimeMillis();for (int i = 0; i < RUN_COUNT; i++) {log.info(Storey1.test());}long start2 = System.currentTimeMillis();for (int i = 0; i < RUN_COUNT; i++) {try {Storey1.testException();} catch (Exception e) {log.info(e.getMessage(), e);}}long end = System.currentTimeMillis();log.info("普通返回耗时:{},异常返回耗时:{}", start2 - start1, end - start1);}public static class Storey1 {public static String test() {return Storey2.test();}public static String testException() {return Storey2.testException();}}public static class Storey2 {public static String test() {return Storey3.test();}public static String testException() {return Storey3.testException();}}public static class Storey3 {public static String test() {return Storey4.test();}public static String testException() {return Storey4.testException();}}public static class Storey4 {public static String test() {return Storey5.test();}public static String testException() {return Storey5.testException();}}public static class Storey5 {public static String test() {return Integer.toString(count++);}public static String testException() {throw new CustomException(Integer.toString(count++));}}public static class CustomException extends RuntimeException {public CustomException(String message) {super(message);}}
结果差别很大,普通返回只要2137毫秒,而异常却要75026毫秒,几十倍的差距 。15:07:59.648 [main] INFO com.alibaba.easytools.test.temp.exception.ExceptionTest - 普通返回耗时:2137,异常返回耗时:75026
不输出堆栈信息聪明的同学不难发现,上面有个变量没控制住,就是使用异常的情况下,输出了堆栈信息,那我们关闭堆栈输出试试 。会不会是输出的堆栈信息导致的慢呢?/*** 测试异常耗时* 仅仅输出信息*/@Testpublic void print() {long start1 = System.currentTimeMillis();for (int i = 0; i < RUN_COUNT; i++) {log.info(Storey1.test());}long start2 = System.currentTimeMillis();for (int i = 0; i < RUN_COUNT; i++) {try {Storey1.testException();} catch (Exception e) {log.info(e.getMessage());}}long end = System.currentTimeMillis();log.info("普通返回耗时:{},异常返回耗时:{}", start2 - start1, end - start1);}
结果发现普通返回是2053毫秒,而异常却要4380毫秒,发现差距瞬间变小了 。15:43:54.260 [main] INFO com.alibaba.easytools.test.temp.exception.ExceptionTest - 普通返回耗时:2053,异常返回耗时:4380
不输出任何信息显然我们发现,关闭了日志输出对执行时间影像很大,那我们关闭了日志输出会有什么效果了呢?/*** 测试异常耗时* 不输出信息*/@Testpublic void noPrint() {long start1 = System.currentTimeMillis();for (int i = 0; i < RUN_COUNT; i++) {Storey1.test();}long start2 = System.currentTimeMillis();for (int i = 0; i < RUN_COUNT; i++) {try {Storey1.testException();} catch (Exception e) {}}long end = System.currentTimeMillis();log.info("普通返回耗时:{},异常返回耗时:{}", start2 - start1, end - start1);}
结果发现普通返回是58毫秒,而异常却要719毫秒,看来性能实际差距就是十几倍 。15:47:55.901 [main] INFO com.alibaba.easytools.test.temp.exception.ExceptionTest - 普通返回耗时:58,异常返回耗时:719
关闭堆栈在处理异常的时候,很多时间在封装异常堆栈,那有没有办法可以不要封装呢?仔细研究异常类发现,异常类有个参数`writableStackTrace` 可以让异常不去封装堆栈信息 。
public class RuntimeException extends Exception {/*** Constructs a new runtime exception with the specified detail* message, cause, suppression enabled or disabled, and writable* stack trace enabled or disabled.** @parammessage the detail message.* @param cause the cause.(A {@code null} value is permitted,* and indicates that the cause is nonexistent or unknown.)* @param enableSuppression whether or not suppression is enabled*or disabled* @param writableStackTrace whether or not the stack trace should*be writable** @since 1.7*/protected RuntimeException(String message, Throwable cause,boolean enableSuppression,boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 林平之到底爱不爱岳灵珊? 林平之爱岳灵珊吗
- 虚假宣传|晴天,阴天,夜钓到底该如何选择钓鱼偏光镜
- 八仙之一的铁拐李的葫芦到底是做什么用的? 铁拐李的葫芦
- “秋天的第一杯奶茶”到底是啥梗? 秋天的第一杯奶茶什么梗
- 菠萝放了一夜还能吃吗 菠萝放了一夜还能不能吃 逃跑吧少年菠萝辅助器
- 五官中郎将这个官职到底是做什么的? 五官中郎将
- 从星盘看你们的姐妹情到底有多深 科技紫微星盘
- 政审|外资工厂招聘工人抢着进,国内工厂反而招工难!两者到底有何区别
- 百度又出新广告,要将反套路进行到底吗? 百度拍照搜题
- 胡鑫宇|胡鑫宇一家清空视频疑似退网,胡家大宅人去楼空!他们到底去哪了