加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在优化Scala代码时首先要查看哪里?

发布时间:2020-12-16 09:21:53 所属栏目:安全 来源:网络整理
导读:我目前需要优化一个太慢的算法的Scala实现.它以功能方式实现,仅使用值(val)和不可变数据结构.我已经记录了重要功能(所以我的代码中有一些可变地图),这使得我的代码的速度快了两倍,我不知道下一步该怎么做. 所以,我不是在寻求有关软件优化的通用建议(例如,首
我目前需要优化一个太慢的算法的Scala实现.它以功能方式实现,仅使用值(val)和不可变数据结构.我已经记录了重要功能(所以我的代码中有一些可变地图),这使得我的代码的速度快了两倍,我不知道下一步该怎么做.

所以,我不是在寻求有关软件优化的通用建议(例如,首先优化您的algortihm,使用分析器,做基准测试…),而不是Scala特定或JVM特定的优化建议.

因此,在尝试优化Scala代码时,我的问题是哪里首先看?通常会导致放缓的常见语言结构或模式是什么?

特别是,我正在寻求以下几点建议:

>我读取(…)结构缓慢,因为每次执行循环体时都会生成一个匿名类.是真的吗是否有任何其他地方生成匿名类? (例如,当使用map()和匿名函数时)
>一般来说,不可变的集合显着慢于可变集合
案例(特别是涉及地图结构)?
> Scala 2.8,2.9和2.10之间是否有显着的性能差异?

解决方法

过去我也不得不优化大量的Scala代码.以下不是一个完整的列表,只是一些可能有助于您的实际观察:

>是的,即使使用Scala 2.10,将for循环更换一段时间也会更快.有关详细信息,请参阅linked talk in the comments.此外,请注意,使用“过滤”(您正在迭代的收集之后的条件)将导致您的条件的盒子/拆箱,这可能对性能有很大的影响(see this post for details).
>不可改变与可变的问题只是通过你要执行的更新数量来解决,而且很难(对我来说)这里给出一个一般的答案.
>到目前为止,我没有观察到2.8,2.9和2.10之间的显着性能差异.但显然这取决于手头的问题.例如,如果您的算法大量使用Range.sum,您将观察到很大的差异(因为现在是2.10中的O(1)).
>我注意到,使用相应的Java集合而不是Scala版本也可能导致显着的加速(像我所说的ballpark-figure这样大约为5-10%).例如,对于一个非常具体的问题,我在微基准中获得了以下结果(显示为运行时间)(请注意:不要从中推广;运行自己的).

ColtBitVector          min:      0.042    avg:      0.245    max:     40.120
JavaBitSet             min:      0.043    avg:      0.165    max:      4.306
JavaHashSet            min:      0.191    avg:      0.716    max:     12.624
JavaTreeSet            min:      0.313    avg:      1.428    max:     64.504
ScalaBitSetImmutable   min:      0.380    avg:      1.675    max:     13.838
ScalaBitSetMutable     min:      0.423    avg:      3.693    max:    457.146
ScalaSetImmutable      min:      0.458    avg:      2.305    max:      9.998
ScalaSetMutable        min:      0.340    avg:      1.332    max:     10.974

目前的问题是计算一个简单的整数集合(具有非常特定的大小和集合数).我想演示的是:选择正确/错误的收藏可以产生重大影响!再次,我认为很难给出这些数据类型中的哪一种选择的一般建议,因为这仅仅告诉我们在这个特殊的交叉问题中的性能(但是在替代方案中我选择了Java的HashSet).另外请注意,此交叉问题不需要可变数据类型.尽管如此,即使在不可变的功能中也可能会出现性能差异(而关于Set是可变集合明显更快,它是BitSet中不可变的集合).因此,根据情况,您可能希望选择不可变的集合,以获得最大性能(谨慎使用).>我被告知,声明一个变量private [this] var foo = …阻止创建getter / setter函数,应该更快(免责声明:我从未在微基准中确认).>当处理泛型类型时,为特定类型定义@specialized版本会导致加速.>尽管我尽量避免泛化,但我可以使用以下内容:尝试使用本地数组.在我的许多基准测试中,我刚刚结束了使用Arrays,考虑到它们在JVM中的实现,这是有道理的.>我想到的一个小点:我观察到使用companion对象(即SomeCollectionName(origCollection:_ *))在手工构造和构造中通过origCollection.toSomeCollectionName构造集合的差异.在许多情况下,后者明显更快.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读