我目前需要优化算法的Scala实现,这太慢了。它是以函数的方式实现的,仅使用值(val)和不可变的数据结构。我已经记住了重要的函数(所以在我的代码中有一些可变的映射),这使得我的代码快了一倍,我想知道下一步该做什么。
所以,我并不是在寻找软件优化的通用建议(例如,首先优化你的算法,使用分析器,做基准测试……)而是针对特定于Scala或特定于JVM的优化建议。
因此,我的问题是,在尝试优化Scala代码时,首先应该从哪里开始?通常会导致速度减慢的常见语言结构或模式是什么?
我特别就以下几点征询意见:
for(...)构造很慢,因为每次执行循环体时都会生成一个匿名类。这是真的吗?有没有生成匿名类的其他地方?(例如,当使用带有匿名函数的map()时)发布于 2013-02-28 00:03:48
在过去,我还不得不优化很多Scala代码。下面不是一个完整的列表,只是一些可能对你有帮助的实际观察:
while替换for循环会更快,即使是在Scala2.10中也是如此。有关这方面的详细信息,请参阅linked talk in the comments。此外,请注意,使用“(see this post for details).ColtBitVector最小值: 0.042平均值: 0.245最大值: 40.120 JavaBitSet最小值: 0.043平均值: 0.165最大值: 4.306 JavaHashSet最小值: 0.191平均值: 0.716最大值: 12.624 JavaTreeSet最小值:0.313Avg:1.428max:457.146 ScalaBitSetImmutable最小值: 64.504平均值: 0.380平均值: 1.675最大值: 13.838 ScalaBitSetMutable最小值: 0.423平均值: 3.693最大值: 9.998 ScalaSetImmutable最小值: 0.458平均值: 2.305最大值:9.998 ScalaSetMutable最小值:0.340Avg:1.332max: 10.974
手头的问题是计算整数集合的简单交集(具有非常特定的集合大小和数量)。我想要演示的是:选择正确/错误的集合可以产生重大影响!同样,我认为很难给出选择这些数据类型中哪种数据类型的一般建议,因为这只告诉我们在这个特殊的交集问题中的性能(但我确实在一些情况下选择了Java的HashSet,而不是其他选择)。还要注意,这个交集问题不需要可变的数据类型。尽管如此,即使在不可变的功能中也可能存在性能差异(尽管对于Set来说,可变集合的速度要快得多,但对于BitSet来说,它是不可变的集合)。因此,根据不同的情况,您可能希望选择可变集合而不是不可变集合来获得最大性能(小心使用!)。
private[this] var foo = ...会阻止创建getter/ @specialized函数,并且应该更快(免责声明:我从未确认过在处理泛型类型的microbenchmark).
@specialized版本应该导致getter。我尽量避免泛化,但我可以接受以下内容:尝试使用本机数组。在我的许多基准测试中,我只是最终使用了数组,考虑到它们在JVM中的实现,这是有意义的。
origCollection.toSomeCollectionName构造集合与使用伴生对象(即SomeCollectionName(origCollection :_*))构造集合的差异。在许多情况下,后者的速度要快得多。发布于 2013-02-27 21:02:04
你的代码在运行时会实例化大量的对象吗?例如,Scala的case类,或者map/flatMap的链会导致大量的“不必要的”对象被创建,这可能会减慢代码的速度并给垃圾回收器带来更多的工作。
https://stackoverflow.com/questions/15112604
复制相似问题