Inspirado por una pregunta de SO: /programming/6623391/how-to-gain-control-of-a-5gb-heap-in-haskell
Puede ser un largo debate sobre las numerosas ventajas y desventajas de FP, pero por ahora, me gustaría limitar el alcance a la eficiencia principal de FP en el hardware moderno.
Tesis:
El paradigma funcional implica inmutabilidad y apatridia (?), Pero el hardware en el que ejecutamos los programas funcionales son autómatas finitos con estado. La traducción del programa "puramente funcional" a una representación de "hardware con estado" deja poco control al programador, conlleva una sobrecarga (?) Y limita el uso de capacidades de hardware (?).
¿Estoy en lo cierto o equivocado en las declaraciones cuestionadas?
¿Se puede demostrar que FP implica / no implica penalizaciones de rendimiento principales en la arquitectura moderna de computadoras de uso general?
EDITAR: Como ya he dicho en respuesta a algunos comentarios, la pregunta no es sobre el rendimiento y los detalles de la implementación. Se trata de la presencia o ausencia de sobrecarga principal , que puede generar la ejecución de FP en autómatas con estado.
running FP on stateful automata
.Respuestas:
Hay un gran malentendido en la inmutabilidad.
La inmutabilidad es una característica de la semántica, pero no implica inmutabilidad en la implementación.
Un ejemplo simple es la implementación de la pereza.
Cuando los cálculos son flojos, el resultado de una expresión es conceptualmente un valor, pero la implementación subyacente es un thunk que contiene los argumentos a evaluar y una función para crear el valor, así como un espacio para almacenar el valor.
La primera vez que preguntará (en el idioma) el valor, se realizará el cálculo, se evaluará su resultado y se le devolverá el valor (o un identificador).
Esto es transparente en la semántica del lenguaje, y todo lo que sabe es que esta variable se ha vinculado a un valor (o un valor futuro) y que una vez que se hace, no puede cambiar el valor que se devolverá. La representación de memoria subyacente cambiará, pero no lo sabrá.
La misma diferencia semántica / implementación existe en casi cualquier idioma, y de hecho es el corazón de la optimización . Cualquiera sea el idioma, la semántica garantiza algunas cosas, pero deja otras sin especificar para dejar espacio para la optimización.
Ahora, es cierto que los lenguajes prácticamente funcionales no son tan rápidos como C ++, por ejemplo. Sin embargo,
Go
(que todavía es una exageración) es más lento que Haskell o Lisp, y también lo es C # Mono ( fuente ).Cuando vea cuán poco confiables pueden ser C ++ o C para obtener esas actuaciones, es posible que desee dejar ir un poco.
Cuando te das cuenta de que Haskell está creciendo rápidamente hoy, y todavía hay mucho espacio para la optimización en su compilador / tiempo de ejecución (GHC acaba de cambiar recientemente a LLVM, por ejemplo, Microsoft Research está financiando activamente las mejoras de tiempo de ejecución), puede estar dispuesto a apostar que Va a mejorar pronto.
Diversión: un juego con expresiones regulares o cómo un equipo de Haskell creó un emparejador de expresiones regulares que supera
re2
, la biblioteca C de Google, en varios escenarios.fuente
El paradigma funcional es útil para dividir cosas en un ámbito estrecho. Esto es algo realmente bueno considerando cómo evoluciona la computadora.
La CPU multinúcleo tiene grandes problemas para lidiar con recursos compartidos y el costo de sincronización es realmente costoso. El paradigma funcional permite una forma natural de expresar programas que no tienen estos problemas. Esto es realmente bueno para el paralelismo.
Además, estamos utilizando granjas de servidores cada vez más con SaaS y la computación en la nube. Por lo tanto, la misma aplicación debe ejecutarse en varias máquinas. En esta posición, los costos de sincronización son aún más costosos. Google ha realizado algunos trabajos y ha publicado algunos trabajos de investigación sobre programación funcional y algoritmos en los que puede escribir. Esto es una cosa clave para ellos porque tienen un problema de escalabilidad.
Además, puede hacer fácilmente una pila en el montón de la computadora, e incluso una no continua utilizando listas vinculadas. Esto ya se hace para generar el seguimiento de la pila en muchos lenguajes de programación. Entonces esto no es un problema.
OK, la programación funcional implica algunas limitaciones. Pero también brinda una forma natural de expresar las problemáticas que tenemos en la informática moderna, que son extremadamente difíciles de manejar en paradigmas a los que estamos acostumbrados. La escalabilidad es uno de ellos, y se está convirtiendo en un verdadero negocio.
Todos los que ya manejan un sistema paralelo complejo saben de lo que estoy hablando.
Entonces matizaría la respuesta. Sí, funcional tiene problemas con el hardware moderno, pero la programación antigua simple también tiene algunos. Como siempre, encontrará ventajas e inconvenientes. El punto es saber cuáles son para que pueda tomar la decisión adecuada cuando sea necesario.
fuente
Realmente no tengo una respuesta, ya que no sé el estado actual o incluso lo difícil que sería, pero solo porque el compilador se aseguraría de esas cosas desde la entrada, no necesariamente significa que la salida las tendría . En teoría, un compilador suficientemente inteligente podría pasar por alto todos estos problemas, pero en la práctica, probablemente siempre existirá.
Sin embargo, otra forma de verlo es mirar la historia de la máquina Lisp. Si no recuerdo mal, fueron diseñados originalmente para superar los mismos problemas que Lisp tuvo con su diferencia con las máquinas de la época. El desarrollo de estas máquinas finalmente se detuvo, ya que el escritorio se volvió lo suficientemente rápido como para hacer que las ineficiencias fueran más baratas para vivir que para soportar otra máquina.
En general, a excepción de la aplicación más crítica para el rendimiento, los lenguajes FP siguen siendo lo suficientemente rápidos. Al elegir cualquier idioma de nivel superior, estará dispuesto a reducir la prioridad en el control y el rendimiento para una seguridad más segura, más fácil, más fácil de mantener u otra prioridad.
Al final, la programación se trata de compensaciones, por lo que uno solo tiene que elegir lo que más importa para el proyecto en cuestión.
fuente
Es cierto que el paradigma funcional implica inmutabilidad y apatridia, pero no tenemos lenguajes de programación completamente puros. Incluso el más puro, Haskell, permite efectos secundarios.
Dicho esto, para responder a su pregunta sobre la eficiencia, he usado tanto Haskell como Clojure, y tampoco he notado ningún problema de rendimiento.
fuente