JavaScriptCore anidado "llamada" problema de rendimiento
(1)
Si defino una función
inc = function(x) { return x + 1 }
y hacer una invocación anidada de ello.
inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(1)))))))))))))))))))))
esto dará como resultado el valor 22
. Si reviso la expresión anidada para hacer uso de la call
, pasa null
para this
, como
inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))))))))))))))))))
Esto también producirá el valor 22
.
Pero, en JavaScriptCore, esta segunda forma parece consumir memoria O (2 ^ n ), donde n es el número de llamadas anidadas. Este no es el caso si intento este JavaScript en Firefox o Chrome por lo que parece estar aislado a JavaScriptCore.
Tengo muy poca experiencia con JavaScript (casi ninguna). No tengo una idea de las ventajas y desventajas que pueden tener varias implementaciones de JavaScript, ni si es razonable que el código de ejemplo sea costoso en algunas implementaciones (que brinde soporte genérico para cierres o algo así), mientras que en otras sea eficiente.
Mi pregunta es: ¿Es este código inherentemente problemático? ¿Debería reescribirse para que se estructure de forma diferente? ¿O está bien el código? ¿Tiene JavaScriptCore simplemente un error?
He realizado algunos experimentos en los que refactorizar algunas de las llamadas internas a los temporales "truncará" el comportamiento de duplicación de la memoria.
var temp1 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))));
var temp2 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp1)))))));
inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp2)))))));
Sobre la base de los comentarios sobre esta pregunta, el consenso es que no hay un problema fundamental con el código como está escrito, sino que este es un error en JavaScriptCore.
Para el bugs.webkit.org/show_bug.cgi?id=139847 , se ha confirmado que es reproducible y se ha importado al sistema de radar de Apple.