繁体   English   中英

是否有可能在WebKit中检测尾调用优化?

[英]Is it possible to detect tail call optimization in WebKit?

我有一个递归函数,耗尽调用堆栈是我遇到的问题。 我知道我可以使用streamTime,使用setTimeout,但我想编写触发尾调用优化的代码。 到目前为止,只有Webkit似乎已经实现了尾调用优化(TCO)。 除了知道理论之外,有没有办法检查我的代码是否会触发TCO,无论是使用devtools还是检查Webkit编译器的输出?

我知道它并不完美,但我认为这是我们目前最好的选择。

考虑这个功能:

"use strict";

function detectTCO() {
    const outerStackLen = new Error().stack.length;
    // name of the inner function mustn't be longer than the outer!
    return (function inner() {
        const innerStackLen = new Error().stack.length;
        return innerStackLen <= outerStackLen;
    }());
}

Error.stack不是标准的,但它在所有现代浏览器中都有基本支持。 它在不同的浏览器中具有不同的值,但是,当较长的命名函数尾部调用较短的命名值时,堆栈跟踪:

  • 使用TCO:变短,因为外部函数的堆栈帧被内部函数的堆栈帧替换。
  • 没有TCO:变长,因为内部函数的堆栈帧被追加。

截至目前,这对于Safari返回true ,对于其他浏览器则返回false ,这是当前的TCO支持。

 "use strict"; function detectTCO() { const outerStackLen = new Error().stack.length; // name of the inner function mustn't be longer than the outer! return (function inner() { const innerStackLen = new Error().stack.length; return innerStackLen <= outerStackLen; }()); } document.getElementById('result').innerText = detectTCO() ? 'Yes' : 'No'; 
 #result { color: blue; font-weight: bold; } 
 Is TCO available? <div id="result"></div> 

可以利用.toString()RegExp.test()来检查return语句后跟下划线或$ sign,az字符; 然后是左括号,后跟任何字符,后跟右括号

 function forEach(arr, callback, start) { if (0 <= start && start < arr.length) { callback(arr[start], start, arr); return forEach(arr, callback, start + 1); // tail call } } console.log(/return [_a-z$]+\\(.*\\)/i.test(forEach.toString())) 

你总是可以用最愚蠢的方式来做 - 在try中运行tail递归函数,用一些“大”参数来捕获块。 如果它抛出则TCO不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM