资讯专栏INFORMATION COLUMN

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

endiat / 1476人阅读

摘要:关键字是用抛异常来实现的,这样就能提前脱离代码块了。通常的异常有三类。于是我们要知道抛异常为什么慢咋解决的和都是很快很快的,毕竟只是几个地址操作,慢的是这一步,这里要让取得当前的一大串填充进去,开销约为个的程度。

另载于 http://www.qingjingjie.com/blogs/11

熟悉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悠着点用啊,玩不好是要出大事的(下一篇谈这个问题)。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64534.html

相关文章

  • Flink 源码解析 —— 深度解析 Flink 是如何管理好内存的?

    摘要:减少垃圾收集压力因为所有长生命周期的数据都是在的管理内存中以二进制表示的,所以所有数据对象都是短暂的,甚至是可变的,并且可以重用。当然,并不是唯一一个基于且对二进制数据进行操作的数据处理系统。 showImg(https://segmentfault.com/img/remote/1460000020044119?w=1280&h=853); 前言 如今,许多用于分析大型数据集的开源系...

    Edison 评论0 收藏0
  • SegmentFault 技术周刊 Vol.40 - 2018,来学习一门新的编程语言吧!

    摘要:入门,第一个这是一门很新的语言,年前后正式公布,算起来是比较年轻的编程语言了,更重要的是它是面向程序员的函数式编程语言,它的代码运行在之上。它通过编辑类工具,带来了先进的编辑体验,增强了语言服务。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不觉已经到来了,总结过去的 2017,相信小伙们一定有很多收获...

    caspar 评论0 收藏0
  • SegmentFault 技术周刊 Vol.40 - 2018,来学习一门新的编程语言吧!

    摘要:入门,第一个这是一门很新的语言,年前后正式公布,算起来是比较年轻的编程语言了,更重要的是它是面向程序员的函数式编程语言,它的代码运行在之上。它通过编辑类工具,带来了先进的编辑体验,增强了语言服务。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不觉已经到来了,总结过去的 2017,相信小伙们一定有很多收获...

    nihao 评论0 收藏0
  • SegmentFault 技术周刊 Vol.40 - 2018,来学习一门新的编程语言吧!

    摘要:入门,第一个这是一门很新的语言,年前后正式公布,算起来是比较年轻的编程语言了,更重要的是它是面向程序员的函数式编程语言,它的代码运行在之上。它通过编辑类工具,带来了先进的编辑体验,增强了语言服务。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不觉已经到来了,总结过去的 2017,相信小伙们一定有很多收获...

    Drummor 评论0 收藏0
  • 品阿里 Java 开发手册有感

    摘要:并发处理书摘第一,线程必须通过线程池来提供,不允许显式创建线程。具体行锁,表锁大家可以自行百度了解。因为它是定义的标准统计行数的预发。二者得保留事故服务器现场。最后感谢小册子阿里巴巴开发手册,感觉不错。 摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! showImg(https://segment...

    bang590 评论0 收藏0

发表评论

0条评论

endiat

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<