performance - revista - Implicaciones de rendimiento del estilo sin puntos
lecturas revista ethos gubernamental (1)
Estoy dando los primeros pasos para mi bebé en el aprendizaje de la programación funcional usando F # y acabo de encontrarme con los operadores Forward Pipe (|>) y Forward Composition (>>). Al principio pensé que solo eran azúcar en lugar de tener un efecto en el código de ejecución final (aunque sé que la tubería ayuda con la inferencia de tipo).
Sin embargo, me encontré con este artículo SO: ¿Cuáles son las ventajas y desventajas del estilo "sin puntos" en la programación funcional? Que tiene dos respuestas interesantes e informativas (que en lugar de simplificar las cosas para mí, abrió una lata de gusanos alrededor del estilo "sin puntos" o "sin sentido") Mi lectura de estas (y otras lecturas) es tan sencilla es un área debatida Al igual que Lambas, el estilo sin puntos puede hacer que el código sea más fácil de entender, o mucho más difícil, dependiendo del uso. Puede ayudar a nombrar las cosas de manera significativa.
Pero mi pregunta se refiere a un comentario sobre la primera respuesta: AshleyF reflexiona en la respuesta:
"Me parece que la composición puede reducir la presión de GC al hacer más obvio para el compilador que no hay necesidad de producir valores intermedios como en el pipeline; ayudando a que el llamado problema de "deforestación" sea más manejable ".
Gasche responde:
"La parte sobre la compilación mejorada no es cierta en absoluto. En la mayoría de los idiomas, el estilo sin puntos realmente reducirá el rendimiento. Haskell depende en gran medida de las optimizaciones precisamente porque es la única manera de hacer que el costo de estas cosas sea llevadero. En el mejor de los casos, esos combinadores están alineados y obtienes una versión equivalente significativa ".
¿Alguien puede ampliar las implicaciones de rendimiento? (En general y específicamente para F #), había asumido que era una cosa de estilo de escritura y el compilador desenredaría ambos modismos en un código equivalente.
Esta respuesta va a ser F # -específica. No sé cómo funcionan las partes internas de otros lenguajes funcionales, y el hecho de que no compilan con CIL podría marcar una gran diferencia.
Puedo ver tres preguntas aquí:
- ¿Cuáles son las implicaciones de rendimiento de usar
|>
? - ¿Cuáles son las implicaciones de rendimiento de usar
>>
? - ¿Cuál es la diferencia de rendimiento entre declarar una función con sus argumentos y sin ellos?
Las respuestas (usando ejemplos de la pregunta a la que se vinculó ):
¿Hay alguna diferencia entre
x |> sqr |> sum
ysum (sqr x)
?No, no hay. El CIL compilado es exactamente el mismo (aquí representado en C #):
sum.Invoke(sqr.Invoke(x))
(Se usa
Invoke()
porquesqr
ysum
no son métodos CIL, sonFSharpFunc
, pero eso no es relevante aquí).¿Hay alguna diferencia entre
(sqr >> sum) x
ysum (sqr x)
?No, ambas muestras compilan al mismo CIL que el anterior.
¿Hay alguna diferencia entre
let sumsqr = sqr >> sum
ylet sumsqr x = (sqr >> sum) x
?Sí, el código compilado es diferente. Si especifica el argumento,
sumsqr
se compila en un método CLI normal. Pero si no lo especifica, se compila como una propiedad del tipoFSharpFunc
con un campo de respaldo, cuyo métodoInvoke()
contiene el código.Pero el efecto de todo es que invocar la versión sin puntos significa cargar un campo (
FSharpFunc
), que no se hace si se especifica el argumento. Pero creo que eso no debería afectar el desempeño de manera medible, excepto en las circunstancias más extremas.