Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
优化Scala代码时,首先要看哪里?_Scala_Optimization - Fatal编程技术网

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

优化Scala代码时,首先要看哪里?,scala,optimization,Scala,Optimization,我目前需要优化一个算法的Scala实现,这个算法太慢了。它是以函数方式实现的,只使用值(val)和不可变的数据结构。我已经记住了重要的函数(因此代码中有一些可变映射),这使我的代码速度提高了一倍,我想知道下一步该怎么做 因此,我不是在寻找关于软件优化的一般建议(例如,首先优化算法,使用分析器,进行基准测试…),而是寻找特定于Scala或JVM的优化建议 因此,我的问题是,在尝试优化Scala代码时,首先要看哪里?通常导致减速的常见的语言结构或模式是什么 我特别就以下几点征求意见: 我读到,fo

我目前需要优化一个算法的Scala实现,这个算法太慢了。它是以函数方式实现的,只使用值(
val
)和不可变的数据结构。我已经记住了重要的函数(因此代码中有一些可变映射),这使我的代码速度提高了一倍,我想知道下一步该怎么做

因此,我不是在寻找关于软件优化的一般建议(例如,首先优化算法,使用分析器,进行基准测试…),而是寻找特定于Scala或JVM的优化建议

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

我特别就以下几点征求意见:

  • 我读到,
    for(…)
    构造很慢,因为每次执行循环体时都会生成一个匿名类。这是真的吗?是否还有其他生成匿名类的地方?(例如,使用带有匿名函数的
    map()
    时)
  • 在一般情况下,不可变集合是否比可变集合慢得多 案例(尤其是涉及到映射结构时)
  • Scala 2.8、2.9和2.10之间是否存在显著的性能差异

您的代码在运行时是否实例化了大量对象?例如,Scala
case
类或
map
/
flatMap
的链可能会导致创建大量“不必要”的对象。这可能会降低代码的速度,并给垃圾收集器带来更多的工作。

过去我还必须优化很多Scala代码。以下并不是一个完整的列表,只是一些可能对您有所帮助的实际观察结果:

  • 是的,将
    for
    循环替换为
    while
    更快,即使使用Scala 2.10也是如此。有关详细信息,请参阅。另外,请注意,使用“for filtering”(您正在迭代的集合后面的一个条件)将导致条件的装箱/拆箱,这可能会对性能产生很大影响()

  • 不可变与可变这个问题的答案很简单,就是您必须执行的更新数量,而且(对我来说)很难在这里给出一般性的答案

  • 到目前为止,我没有观察到2.8、2.9和2.10之间存在显著的性能差异。但这显然取决于手头的问题。例如,如果您的算法大量使用Range.sum,您将观察到很大的差异(因为在2.10中这是O(1))

  • 我注意到,使用相应的Java集合而不是Scala版本也可以带来显著的速度提升(如大致数字所示,我可以说是5-10%)。例如,对于一个非常具体的问题,我在微基准中得到了以下结果(显示的是运行时)(注意:不要从中概括,运行您自己的)

    目前的问题是计算整数集的简单交集(具有非常特定的大小和集合数)。我想展示的是:选择正确/错误的收藏会产生重大影响!同样,我认为很难给出选择哪种数据类型的一般建议,因为这只告诉我们在这个特殊的交集问题中的性能(但我确实在一些情况下选择了Java的
    HashSet
    )。另外,请注意,此交叉点问题不需要可变数据类型。然而,即使在不可变功能中也可能存在性能差异(而对于
    Set
    ,可变集合的速度要快得多,而对于
    BitSet
    ,它是不可变的)。因此,根据具体情况,您可能希望选择可变集合而不是不可变集合以获得最大性能(小心使用!)

  • 我被告知声明一个变量
    private[this]var foo=…
    会阻止getter/setter函数的创建,并且应该更快(免责声明:我从未在微基准中确认过这一点)

  • 在处理泛型类型时,为特定类型定义
    @specialized
    版本应该会加快速度

  • 尽管我试图避免泛化,但我可以接受以下情况:尝试使用本机数组。在我的许多基准测试中,我只是使用了数组,考虑到它们在JVM中的实现,这是有意义的

  • 我想到的一个小问题是:我观察到通过
    origCollection.toSomeCollectionName
    构造集合与手动构造和使用伴生对象(即
    SomeCollectionName(origCollection:*)
    )构造集合的不同之处。在许多情况下,后者的速度要快得多


虽然这是一个有趣的问题,需要有趣的答案,但我认为这不适合stackoverflow,因为它太过开放(请参阅)。您最好将此问题发布在programmers.stackexchange上。com@RégisJean-Gilles:老实说,在发布之前,我想知道这个问题是否适合stackoverlow(我认为这是一个“边缘”问题)。我把它贴在这里是因为我在寻找实用的和scala特有的建议,而不是理论上的和一般的优化建议。如果第四次投票结果接近,我会将其删除并发布在programmers.stackexchange.com上。从NE Scala 2011@nermin Serifovicala,这个问题需要一本书来回答,但没有这样的书。只有一小部分现有工作(例如“Java性能调优”)可能与此相关。无论如何,这个问题太宽泛了,无法以这种形式给出一个好的答案,因此并不适合这样做。@DenisTulskiy看看汇编,我听说它也很震撼;-)我不是说这是主要的问题
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