斯卡拉表演:势在必行vs功能风格 [英] Scala Performance: imperative vs functional style

查看:98
本文介绍了斯卡拉表演:势在必行vs功能风格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Scala的新手,只是阅读 Scala By Example 。在第2章中,作者有两种不同的Quicksort版本。



其中一种是势在必行的风格:

  def sort(xs:Array [Int]){
def swap(i:Int,j:Int){
val t = xs(i); xs(i)= xs(j); xs(j)= t
}
def sort1(l:Int,r:Int){
val pivot = xs((l + r)/ 2)
var i = 1; (xs(j)> pivot)j(xs(j)> pivot)时,j = r
(i <= j){
while - = 1
if(i <= j){
swap(i,j)
i + = 1
j - = 1
}
} (1,j)
if(j< r)sort1(i,r)
}
sort1(0,xs.length) - 1)
}

一种是功能性风格:

  def sort(xs:Array [Int]):Array [Int] = {
if(xs.length <= 1)xs
$ {
val $ x $(b



$ b $ x $ filter $ {$ b $ ==),
sort(xs filter(pivot))

$ b $ $
$ b

功能风格比命令风格简洁明显。但是表演呢?由于它使用递归,我们是否像在其他命令式语言如C中那样支付性能损失?或者,Scala是一种混合语言,Scala方式(功能性)是首选,因此效率更高。注意:作者确实提到了功能风格确实使用更多记忆。

解决方案

这取决于。如果你看看Scala的源代码,通常会有一种强制性的风格被用在引擎盖下,以便高性能 - 但在许多情况下,这些调整正好可以让你写入高性能的功能代码。所以通常你可以想出一个足够快的功能性解决方案,但是你必须小心并且知道你在做什么(尤其是关于你的数据结构)。例如。第二个例子中的数组concat并不好,但可能不会太糟 - 但是在这里使用Lists并将它们连接到:::将会过度杀伤。



但是,如果你实际上没有衡量表现,那么不会超过受过教育的猜测。在复杂的项目中,真的很难预测性能,特别是像对象创建和方法调用这样的东西,越来越多的被编译器和JVM优化。

建议从功能风格开始。如果速度太慢,请对其进行分析。通常有更好的功能解决方案。如果没有,您可以使用命令式(或两者兼而有之)作为最后的手段。


I'm new to Scala and was just reading Scala By Example. In chapter 2, the author has 2 different versions of Quicksort.

One is imperative style:

def sort(xs: Array[Int]) {
    def swap(i: Int, j: Int) {
        val t = xs(i); xs(i) = xs(j); xs(j) = t
    }
    def sort1(l: Int, r: Int) {
        val pivot = xs((l + r) / 2)
        var i = l; var j = r
        while (i <= j) {
            while (xs(i) < pivot) i += 1
            while (xs(j) > pivot) j -= 1
            if (i <= j) {
                swap(i, j)
                i += 1
                j -= 1
            }
        }
        if (l < j) sort1(l, j)
        if (j < r) sort1(i, r)
    }
    sort1(0, xs.length - 1)
}

One is functional style:

def sort(xs: Array[Int]): Array[Int] = {
  if (xs.length <= 1) xs
  else {
    val pivot = xs(xs.length / 2)
    Array.concat(
      sort(xs filter (pivot >)),
           xs filter (pivot ==),
      sort(xs filter (pivot <)))
  }
}

The obvious advantage the functional style has over imperative style is conciseness. But what about performance? Since it uses recursion, do we pay for the performance penalty just like we do in other imperative languages like C? Or, Scala being a hybrid language, the "Scala way" (functional) is preferred, thus more efficient.

Note: The author did mention the functional style does use more memory.

解决方案

It depends. If you look in the Scala sources, there is often an imperative style used "under the hood" in order to be performant - but in many cases exactly these tweaks allow you write performant functional code. So usually you can come up with a functional solution that is fast enough, but you must be careful and know what you do (especially concerning your data structures). E.g. the array concat in the second example is not nice, but probably not too bad - but using Lists here and concat them with ::: would be overkill.

But that is not more than educated guessing if you don't actually measure the performance. In complex projects it's really hard to predict the performance, especially as things like object creation and method calls get more and more optimized by the compiler and the JVM.

I'd suggest to start out with the functional style. If it is too slow, profile it. Usually there is a better functional solution. If not, you can use the imperative style (or a mix of both) as a last resort.

这篇关于斯卡拉表演:势在必行vs功能风格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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