优化Scala代码时,首先要看哪里?
我目前需要优化一个算法的Scala实现,这个算法太慢了。它是以函数方式实现的,只使用值(优化Scala代码时,首先要看哪里?,scala,optimization,Scala,Optimization,我目前需要优化一个算法的Scala实现,这个算法太慢了。它是以函数方式实现的,只使用值(val)和不可变的数据结构。我已经记住了重要的函数(因此代码中有一些可变映射),这使我的代码速度提高了一倍,我想知道下一步该怎么做 因此,我不是在寻找关于软件优化的一般建议(例如,首先优化算法,使用分析器,进行基准测试…),而是寻找特定于Scala或JVM的优化建议 因此,我的问题是,在尝试优化Scala代码时,首先要看哪里?通常导致减速的常见的语言结构或模式是什么 我特别就以下几点征求意见: 我读到,fo
val
)和不可变的数据结构。我已经记住了重要的函数(因此代码中有一些可变映射),这使我的代码速度提高了一倍,我想知道下一步该怎么做
因此,我不是在寻找关于软件优化的一般建议(例如,首先优化算法,使用分析器,进行基准测试…),而是寻找特定于Scala或JVM的优化建议
因此,我的问题是,在尝试优化Scala代码时,首先要看哪里?通常导致减速的常见的语言结构或模式是什么
我特别就以下几点征求意见:
- 我读到,
构造很慢,因为每次执行循环体时都会生成一个匿名类。这是真的吗?是否还有其他生成匿名类的地方?(例如,使用带有匿名函数的for(…)
时)map()
- 在一般情况下,不可变集合是否比可变集合慢得多 案例(尤其是涉及到映射结构时)
- Scala 2.8、2.9和2.10之间是否存在显著的性能差异
case
类或map
/flatMap
的链可能会导致创建大量“不必要”的对象。这可能会降低代码的速度,并给垃圾收集器带来更多的工作。过去我还必须优化很多Scala代码。以下并不是一个完整的列表,只是一些可能对您有所帮助的实际观察结果:
- 是的,将
循环替换为for
更快,即使使用Scala 2.10也是如此。有关详细信息,请参阅。另外,请注意,使用“for filtering”(您正在迭代的集合后面的一个条件)将导致条件的装箱/拆箱,这可能会对性能产生很大影响()while
- 不可变与可变这个问题的答案很简单,就是您必须执行的更新数量,而且(对我来说)很难在这里给出一般性的答案
- 到目前为止,我没有观察到2.8、2.9和2.10之间存在显著的性能差异。但这显然取决于手头的问题。例如,如果您的算法大量使用Range.sum,您将观察到很大的差异(因为在2.10中这是O(1))
- 我注意到,使用相应的Java集合而不是Scala版本也可以带来显著的速度提升(如大致数字所示,我可以说是5-10%)。例如,对于一个非常具体的问题,我在微基准中得到了以下结果(显示的是运行时)(注意:不要从中概括,运行您自己的)
目前的问题是计算整数集的简单交集(具有非常特定的大小和集合数)。我想展示的是:选择正确/错误的收藏会产生重大影响!同样,我认为很难给出选择哪种数据类型的一般建议,因为这只告诉我们在这个特殊的交集问题中的性能(但我确实在一些情况下选择了Java的
)。另外,请注意,此交叉点问题不需要可变数据类型。然而,即使在不可变功能中也可能存在性能差异(而对于HashSet
,可变集合的速度要快得多,而对于Set
,它是不可变的)。因此,根据具体情况,您可能希望选择可变集合而不是不可变集合以获得最大性能(小心使用!)BitSet
- 我被告知声明一个变量
会阻止getter/setter函数的创建,并且应该更快(免责声明:我从未在微基准中确认过这一点)private[this]var foo=…
- 在处理泛型类型时,为特定类型定义
版本应该会加快速度@specialized
- 尽管我试图避免泛化,但我可以接受以下情况:尝试使用本机数组。在我的许多基准测试中,我只是使用了数组,考虑到它们在JVM中的实现,这是有意义的
- 我想到的一个小问题是:我观察到通过
构造集合与手动构造和使用伴生对象(即origCollection.toSomeCollectionName
)构造集合的不同之处。在许多情况下,后者的速度要快得多SomeCollectionName(origCollection:*)
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