Scala 性能问题 [英] Scala performance question

查看:55
本文介绍了Scala 性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在丹尼尔撰写的文章中Korzekwa,他说以下代码的性能:

In the article written by Daniel Korzekwa, he said that the performance of following code:

list.map(e => e*2).filter(e => e>10)

比使用 Java 编写的迭代解决方案差很多.

is much worse than the iterative solution written using Java.

谁能解释一下为什么?Scala 中此类代码的最佳解决方案是什么(我希望它不是 Scala 的 Java 迭代版本)?

Can anyone explain why? And what is the best solution for such code in Scala (I hope it's not a Java iterative version which is Scala-fied)?

推荐答案

那个 特定代码运行缓慢的原因是因为它在处理基元但它使用的是泛型操作,因此必须对基元进行装箱.(如果 List 和它的祖先是专门化的,这可以得到改进.)这可能会使速度减慢 5 倍左右.

The reason that particular code is slow is because it's working on primitives but it's using generic operations, so the primitives have to be boxed. (This could be improved if List and its ancestors were specialized.) This will probably slow things down by a factor of 5 or so.

此外,从算法上讲,这些操作有点昂贵,因为您创建了一个完整的列表,然后创建了一个全新的列表,将中间列表的一些组件丢弃了.如果你一口气做到了,那你会过得更好.你可以这样做:

Also, algorithmically, those operations are somewhat expensive, because you make a whole list, and then make a whole new list throwing a few components of the intermediate list away. If you did it in one swoop, then you'd be better off. You could do something like:

list collect (case e if (e*2>10) => e*2)

但是如果计算 e*2 真的很昂贵怎么办?那么你可以

but what if the calculation e*2 is really expensive? Then you could

(List[Int]() /: list)((ls,e) => { val x = e*2; if (x>10) x :: ls else ls }

除了这会向后显示.(如果需要,您可以反转它,但这需要创建一个新列表,这在算法上也不是理想的.)

except that this would appear backwards. (You could reverse it if need be, but that requires creating a new list, which again isn't ideal algorithmically.)

当然,如果您使用单向链表,您在 Java 中会遇到同样类型的算法问题——您的新列表将向后结束,或者您必须创建两次,先是反向,然后是向前,或者您必须使用(非尾)递归来构建它(这在 Scala 中很容易,但不建议使用任何一种语言进行此类事情,因为您会耗尽堆栈),或者您必须创建一个可变列表,然后假装之后它不是可变的.(顺便说一下,您也可以在 Scala 中执行此操作——请参阅 mutable.LinkedList.)

Of course, you have the same sort of algorithmic problems in Java if you're using a singly linked list--your new list will end up backwards, or you have to create it twice, first in reverse and then forwards, or you have to build it with (non-tail) recursion (which is easy in Scala, but inadvisable for this sort of thing in either language since you'll exhaust the stack), or you have to create a mutable list and then pretend afterwards that it's not mutable. (Which, incidentally, you can do in Scala also--see mutable.LinkedList.)

这篇关于Scala 性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆