node --trace-opt 和 --trace-deopt 输出十六进制和 sfi,但并不总是函数名。所以我想知道是否有任何其他标志我可以设置以了解哪个函数正在优化/去优化。 (这些科目超出了我的知识水平,但我真的很好奇)
我查看了 --v8-options 的其他可用标志,检查了其他跟踪和日志标志的输出。
不是所有的函数都有名字。当一个函数没有名字时,V8 不能打印一个——你希望它打印什么名字?
例如:当你写:
function sum1(a, b) { return a + b; }
for (let i = 0; i < 1e5; i++) sum1(2, 3);
你会在
--trace-opt
输出中看到:
[marking 0x2a920019a879 <JSFunction sum1 (sfi = 0x2a920019a609)> for optimization ...
对于一些技术上没有名称的函数,甚至还有一些名称推断,如存储在全局变量中的匿名函数示例所示:
var sum2 = function(a, b) { return a + b; }
for (let i = 0; i < 1e5; i++) sum2(2, 3);
给:
[marking 0x2a920004e101 <JSFunction sum2 (sfi = 0x2a920019a63d)> for optimization ...
然后是真正的匿名函数,特别倾向于作为回调出现:
for (let i = 0; i < 1e5; i++) ((a, b) => a + b)(2, 3);
for (let i = 0; i < 1e5; i++) (function(a, b) { return a + b; })(2, 3);
不能给你比以下更有意义的东西:
[marking 0x2a920009d379 <JSFunction (sfi = 0x2a920019a671)> for optimization
您可能从中得出的一个结论是,对于可检查性/分析/堆栈跟踪/等,确保所有函数都有名称是有意义的。
匿名函数的一个特例是顶层的代码。顶层很少在实际代码中得到优化,但往往会在小示例(如上面的代码片段)中得到很多优化,在这些示例中,人们只是将长时间运行的
for
循环放入顶层,从而导致 OSR 优化。也许这就是让你困惑的地方。这也可以手动解决以获得更具描述性的跟踪输出:只需将其他所有内容包装到一个函数中,如下所示:
(function toplevel() {
// Your code here, e.g.:
function sum1(...) ...
for (...) sum1(...);
})();