异常高效使用小窍门 -- 读Scala源码有感

周末加班
• 阅读 3863

熟悉Scala的人知道返回值是代码块的最后一句,一般不能提前返回。return关键字是用抛异常来实现的,这样就能提前脱离代码块了。

最近看Scala源代码,注意到它对return的高效实现,有趣。

Scala咋实现的?

抛的异常类是NonLocalReturnControl,继承自Throwable,有个字段用来放置要返回的值。编译器把return value大致翻译成throw new NonLocalReturnControl(key/*metadata*/, value)就可以了。

通常Java的异常有三类: Exception, RuntimeException, Error。如果一个对象是Exception但不是RuntimeException,那就是checked exception。而Error通常是JVM抛出的,例如StackOverflowError, OutOfMemoryError, VerifyError,偶尔也有XML库抛Error。总之没有其他直接继承Throwable的类了。

所以在Scala里只要注意别无脑catch Throwable,就不会误拦return了。如果是个服务器程序,不想let it crash,只要catch Exception和Error就好了。

用抛异常来打断控制流的做法,在有的Web框架中也出现了,没啥。但在一门语言的实现中,必须保证高效。

于是我们要知道抛异常为什么慢!Scala咋解决的?

throw和catch都是很快很快的,毕竟只是几个地址操作,慢的是new Exception这一步,这里要让JVM取得当前的一大串stacktrace填充进去,开销约为new 200个Object的程度。

Scala的NonLocalReturnControl的窍门是——Override了fillInStackTrace()方法。这个方法本来会调用native的fillInStackTrace(int)让JVM去填stacktrace。覆盖成空实现,测一下,开销约为new 6个Object。效果拔群!

还可以提高!去掉synchronized关键字,开销又减半了。最后是new 3个Object的开销,可以接受!

我想到另一种实现方案是把value塞到一个ThreadLocal里,异常就不必包含value了,这样就只需全局new一次异常对象,每次都throw它。开销约为new 1个Object。Clojure就喜欢用ThreadLocal来实现一些特性。不过ThreadLocal悠着点用啊,玩不好是要出大事的(下一篇谈这个问题)。

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
Flink on YARN部署快速入门指南
Apache Flink是一个高效、分布式、基于Java和Scala(主要是由Java实现)实现的通用大数据分析引擎,它具有分布式MapReduce一类平台的高效性、灵活性和扩展性以及并行数据库查询优化方案,它支持批量和基于流的数据分析,且提供了基于Java和Scala的API。  从Flink官方文档可以知道,目前Flink支持三大部署模式:Loca
Stella981 Stella981
3年前
Scala学习(一):Scala简介与Hello World!
一.Scala是什么Scala是一门多范式的编程语言,类似于Java。设计初衷是实现可伸缩的语言、并集成面向对象编程和函数式编程的各种特性。二.环境准备(以Windows下安装Scala为例)1.官网:http://www.scalalang.org/ 下载安装包:!image(https://static.osc
Stella981 Stella981
3年前
Scala快速入门系列
写在前面的话因为Spark是由Scala开发的,所以在开发Spark应用程序之前要对Scala语言学习。虽然Spark也支持Java、Python语言,但是作为一名Java程序猿,还是决定要学习Scala哈。Scala是运行在JVM上一门语言。开发效率非常高、语法丰富简洁,三两行Scala代码能搞定Java要写的一大坨代码。
Stella981 Stella981
3年前
Spark机器学习算法
Spark是一个大规模的数据处理引擎,集成了SQL查询分析,该引擎是用Scala写的,所以一些高级的实现了的算法都是用它进行描述。已知支持的第三方语言有:C【https://github.com/Microsoft/Mobius,Java,Scala,Python,R【http://spark.apache.org】一般性理解:Spark
Stella981 Stella981
3年前
Scala系列4:轻松搞定Scala中for,if,while,块表达式等
0.条件表达式   条件表达式一般就是if表达式,if表达式可以根据给定的条件是否满足,根据条件的结果(真或假)决定执行对应的操作。scala条件表达式的语法和Java一样。0.1有返回值的if条件表达式_尖叫提示:_在scala中,跟Java不同,条件表达式也是有返回值的s
Stella981 Stella981
3年前
Spark学习之Spark安装
Spark安装spark运行环境spark是Scala写的,运行在jvm上,运行环境为java7如果使用Python的API,需要使用Python2.6或者Python3.4Spark1.6.2  Scala2.10  Spark2.0.0  Scala 2.11
Stella981 Stella981
3年前
Spark框架:Win10系统下搭建Scala开发环境
一、Scala环境基础Scala对Java相关的类,接口进行了包装,所以依赖Jvm环境。Jdk1.8scala依赖scala2.11安装版本idea2017.3开发工具二、配置Scala解压版1)注意路径无空格和中文!(http
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
周末加班
周末加班
Lv1
能够慢慢培养的不是感情而是习惯
文章
3
粉丝
0
获赞
0