Recientemente he aprendido Haskell, y estoy tratando de llevar el estilo funcional puro a mi otro código cuando sea posible. Un aspecto importante de esto es tratar todas las variables como inmutables, es decir, constantes. Para hacerlo, muchos cómputos que se implementarían usando bucles en un estilo imperativo se deben realizar usando la recursión, que típicamente incurre en una penalización de memoria debido a la asignación de un nuevo marco de pila para cada llamada de función. En el caso especial de una llamada de cola (donde el valor de retorno de una función llamada se devuelve inmediatamente a la persona que realiza la llamada), esta penalización puede pasar por alto mediante un proceso llamado optimización de llamada de cola (en un método, esto se puede hacer haciendo esencialmente reemplazando una llamada con un jmp después de configurar la pila correctamente). ¿MATLAB realiza el TCO de manera predeterminada, o hay alguna forma de decírselo?¿MATLAB realiza la optimización de la cola de llamada?
Respuesta
Si defino un simple recursiva de cola función:
function tailtest(n)
if n==0; feature memstats; return; end
tailtest(n-1);
end
y lo llamo para que se recursivo bastante profundamente:
set(0,'RecursionLimit',10000);
tailtest(1000);
entonces no se ve como si son marcos de pila comiendo mucha memoria Sin embargo, si lo hago recursivo mucho más profundo:
set(0,'RecursionLimit',10000);
tailtest(5000);
a continuación (en mi máquina, en la actualidad) MATLAB simplemente se estrella: el proceso muere sin contemplaciones.
No creo que esto sea consistente con MATLAB haciendo cualquier TCO; el caso donde una función se llama a sí misma, solo en un lugar, sin variables locales que no sean un solo argumento, es casi tan simple como cualquiera podría esperar.
Así que: No, parece que MATLAB no hace TCO en absoluto, al menos de forma predeterminada. Hasta ahora no he buscado opciones que puedan habilitarlo. Me sorprendería si hubiera alguno.
En los casos en que no apagamos la pila, ¿cuánto cuesta la recursividad? Vea mi comentario a la respuesta de Bill Cheatham: parece que el tiempo de sobrecarga no es trivial, pero no es una locura.
... Excepto que Bill Cheatham borró su respuesta después de que dejara ese comentario. DE ACUERDO. Entonces, tomé una implementación iterativa simple de la función de Fibonacci y una simple recursiva de cola, haciendo esencialmente el mismo cálculo en ambos, y los sincronicé ambos en fib(60)
. La implementación recursiva tomó aproximadamente 2.5 veces más tiempo para ejecutarse que la iterativa. Por supuesto, la sobrecarga relativa será menor para las funciones que hacen más trabajo que una adición y una resta por iteración.
(También estoy de acuerdo con el sentimiento de delnan:. Código altamente recursivo del tipo que se siente natural en Haskell es típicamente probable que sea unidiomatic en MATLAB)
TCO podría ser difícil en Matlab porque la limpieza de variables locales del espacio de trabajo de un marco de pila puede tener efectos secundarios con el onCleanup() característica. Matlab no tiene GCed estilo Java; es determinista, usando recuentos de referencia o similares. Admite RAII. Para determinar si la elisión del marco de pila era segura, tendría que realizar una búsqueda profunda de todas las variables locales que no se pasaron en la llamada final para ver si contenían alguno en Limpiar. Prueba costosa Además, es posible que deba conservarse al menos un marco de pila padre en caso de que se invoque assignin (..., 'caller') o evalin (..., 'caller'). Convenido; unidiomatic. –
- 1. ¿Frege realiza la optimización de la cola de llamada?
- 2. ¿Ruby realiza optimización de llamadas de cola?
- 3. ¿array_walk_recursive utiliza la optimización de la cola de cola?
- 4. C optimización de llamadas de cola
- 5. optimización de llamadas de cola en Mathematica?
- 6. CUDA y MATLAB para la optimización de bucle
- 7. R equivalente al fmincon de MATLAB para la optimización restringida?
- 8. ¿Qué hilo ejecuta la devolución de llamada cuando se realiza una llamada de Servicios RIA asíncrona?
- 9. optimización de matlab para el ciclo
- 10. ¿Scala es compatible con la optimización de la recursividad de cola?
- 11. Intel C++ Compiler comprensión de lo que la optimización se realiza
- 12. Falló la devolución de llamada llamada aunque se realiza la solicitud Ajax y el servidor devuelve 200 con datos
- 13. Salida de la consola MATLAB
- 14. Optimización de la memoria Redis
- 15. ¿Por qué el compilador de Scala no aplicará la optimización de la cola de cola a menos que un método sea definitivo?
- 16. ¿Dónde se realiza la validación?
- 17. ¿Cómo se realiza la validación de dirección?
- 18. ¿Dónde se realiza la anulación de funciones?
- 19. Optimización de la creación de entorno Jinja2
- 20. ¿Cómo realiza Minecraft la iluminación?
- 21. Mover el mensaje de la cola de la carta muerta a la cola de salida MSMQ
- 22. JERSEY: ¿Cómo recuperar la IP o el URI que realiza la llamada utilizando la anotación de inyección?
- 23. Explícame cuál es el gran problema con la optimización de la cola de llamadas y por qué Python lo necesita
- 24. Obtengo una StackOverFlowException en este código porque mi JVM no es compatible con la optimización de llamadas de cola, ¿verdad?
- 25. Optimización de la manipulación de la secuencia F #
- 26. Optimización de Java: variable local o llamada de función
- 27. Ordenando una cola usando la misma cola
- 28. ¿Evita la JVM las optimizaciones de cola?
- 29. ¿Cuál es la diferencia entre la "cola global" y la "cola principal" en GCD?
- 30. VS2010 C++ optimización
Evitar iteración sólo por el gusto de hacerlo no es una buena idea. Use lo que sea más apropiado para el problema dado (y viable; por supuesto, la iteración no es práctica en un lenguaje puramente funcional). – delnan
Con la optimización adecuada de la llamada de cola, "evitar la iteración" se convierte en una cuestión de cómo piensas sobre el problema, no cómo funciona la solución. Si MATLAB no ofrece TCO, entonces obviamente usaré la iteración cuando sea necesario, pero si lo hago, podré usar un paradigma consistente en todo mi código. –
No conozco ningún MATLAB en particular, estoy hablando en general. Si estuviera codificando Python, y Python tenía TCO, aún no debería usar recursion over loops, porque no es idiomático, el lenguaje y stdlib están enfocados en obtener el máximo provecho de los iteradores, etc. Y con respecto al "paradigma consistente": cada uno el paradigma tiene sus puntos débiles, por lo tanto, use lo que sea que resuelva mejor un problema determinado (la definición de "mejor" también implica qué tan bien funciona junto con el resto, por supuesto). – delnan