2010-07-25 16 views
7

Soy nuevo en Scala y solo estaba leyendo Scala By Example. En el capítulo 2, el autor tiene 2 versiones diferentes de Quicksort.Scala Rendimiento: estilo imperativo vs funcional

Uno de ellos es el estilo imperativo:

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) 
} 

Uno de ellos es el estilo funcional:

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 <))) 
    } 
} 

La ventaja obvia el estilo funcional tiene sobre el estilo imperativo es la concisión. ¿Pero qué hay del rendimiento? Dado que usa recursividad, ¿pagamos la penalización de rendimiento tal como lo hacemos en otros lenguajes imperativos como C? O, como Scala es un lenguaje híbrido, se prefiere el "modo Scala" (funcional), por lo tanto, más eficiente.

Nota: El autor mencionó que el estilo funcional usa más memoria.

+2

posible duplicado de [¿Es la programación funcional de scala más lenta que la codificación tradicional?] (Http://stackoverflow.com/questions/2794823/is-scala-functional-programming-slower-than-traditional-coding) – missingfaktor

+2

"Concise" no es lo mismo que "legible". Evidencia: [el lenguaje de programación J] (http://en.wikipedia.org/wiki/J_ (programming_language)) –

+1

Creo que ahora entiendo que el autor de Scala By Example intenta mostrar otra forma de resolver el problema que es mucho más conciso. Para resumir: programa lo más conciso posible en todas las partes de tu código, para que obtengas máxima concisión, productividad. Luego ejecute su aplicación, y si es demasiado lenta, perfilela y optimice las partes de cuello de botella. – sivabudh

Respuesta

11

Depende. Si mira en las fuentes de Scala, a menudo hay un estilo imperativo que se usa "debajo del capó" para ser un rendimiento, pero en muchos casos exactamente estos ajustes permiten escribir código funcional. Por lo general, puede encontrar una solución funcional que sea lo suficientemente rápida, pero debe tener cuidado y saber lo que hace (especialmente en lo que respecta a sus estructuras de datos). P.ej. la matriz concat en el segundo ejemplo no es agradable, pero probablemente no está mal, pero usar las listas aquí y concat con ellos sería demasiado.

Pero eso no es más que una conjetura educada si en realidad no mide el rendimiento. En proyectos complejos, es realmente difícil predecir el rendimiento, especialmente cuando cosas como la creación de objetos y las llamadas a métodos se optimizan cada vez más con el compilador y la JVM.

Sugiero comenzar con el estilo funcional. Si es demasiado lento, perfúlalo. Por lo general, hay una mejor solución funcional. De lo contrario, puede usar el estilo imperativo (o una combinación de ambos) como último recurso.

+0

Pero de alguna manera se derrota el propósito ¿verdad? Quiero decir, Scala es aclamado como el primer lenguaje que une programación funcional y de objetos. Pero, si no puede estar seguro de que la programación de la manera funcional será eficiente, entonces las personas que se preocupan por el rendimiento terminarán haciendo Scala al estilo "Java". – sivabudh

+5

Mira los ejemplos. ¿Cuál parece más fácil de comprender? El estilo funcional realmente te dice lo que hace el algoritmo: "elige un elemento de pivote, clasifica los elementos más pequeños, clasifica los elementos más grandes y reúne todo". Esta es una gran ventaja sobre el ejemplo imperativo, que está principalmente preocupado por las variables de bucle y los índices de matriz. Entonces, si el estilo funcional funciona bien, generalmente somos dorados, pero todavía tenemos el estilo imperativo como solución de recuperación. Sin embargo, no configure orientado a objetos == imperativo. Las clases y los objetos pueden funcionar muy bien en un contexto funcional. – Landei

+9

En cualquier proyecto grande, encontrará que muy poco del código en realidad tiene que ser increíblemente eficiente. En esos casos, es cierto que a menudo tendrá que recurrir a construcciones imperativas. Scala lo apoya.El resto del tiempo, es mejor que codifique de tal manera que su diseño sea tan claramente evidente en su código como sea posible. Eso puede ser funcional, de procedimiento, orientado a objetos o alguna combinación de los mismos. Scala es compatible con todos ellos. –

Cuestiones relacionadas