在 Javascript 中尝试/捕捉会慢多少?

How much slower will try/catch be in Javascript?

提问人:Karamell 提问时间:10/27/2023 最后编辑:Karamell 更新时间:10/27/2023 访问量:66

问:

我有一个函数,每帧都调用它,需要在 16 毫秒内完成(有时它甚至无法管理)。我的团队正在处理这种方法偶尔的例外情况,我想把它包装在 try/catch 中。

我试图更好地理解这里的性能影响,因为网上似乎没有很好的资源来描述在哪些情况下或会降低多少性能。我发现了一篇非常古老的博客文章,声称窗口错误事件将是处理这种情况的更高性能的方式。

这里有人可以分享一些关于这个主题的知识,和/或基准吗?

JavaScript 性能 异常

评论

2赞 Pointy 10/27/2023
好吧,使优化器难以完成其工作。这取决于运行时。但是,您没有发布任何代码,具体细节很重要。try / catch
0赞 Pointy 10/27/2023
我严重怀疑使用会提高性能。最好的办法是让代码不引发异常(除非在真正特殊的情况下)。window.onerror()
0赞 Karamell 10/27/2023
@Pointy在这种情况下,我们希望捕获异常是因为错误,而不是因为故意抛出。另外,您能否详细说明为什么您怀疑这不会改善这种情况?window.onerror
1赞 Pointy 10/27/2023
嗯,全局错误处理机制是一个相当广泛的东西。就像我说的,如果你的异常是由于错误造成的,我的观点是修复错误比异常处理架构更重要。在修复错误时使用简单的 try/catch 可能是最简单的事情。
0赞 Karamell 10/27/2023
@Pointy为了在野外捕获错误,我们希望依靠 try/catch,以便我们可以拥有监控工具来修复问题。如果我们不这样做,我们就无法知道我们是否存在错误。互联网是一个非常多样化的地方,有许多类型的设备和情况最终会扔到意想不到的地方。这并不是“修复错误然后删除 try/catch”的问题。这是一个关于长期解决方案和监控大型产品质量的解决方案

答:

1赞 Bergi 10/27/2023 #1

那篇文章是 2013 年的,完全过时了。在快速发展的网络中,十年是永恒的。

这种结构的独特之处在于捕获的方式 块增强了作用域链。而不是创建新的执行 上下文并将其推送到执行堆栈的顶部,该块实际上将创建一个新的变量对象并将其放在 当前执行的作用域链中的激活对象 上下文。这将创建所谓的动态作用域,类似于 该声明的影响,这使其声誉不佳 井。因此,传递给块的错误对象不会 存在于它之外,甚至在同一范围内。它是在 子句的开头,并在子句末尾销毁。这种类型的 作用域链的操纵是 性能受到打击。catchwithcatchcatch

自从 ES6 引入了块作用域以来,情况就不再如此了。以前,catch 块是例外,但它们仍然只引入嵌套作用域,而不是像语句那样具有任意名称的动态作用域,因此比较永远不会成立。with

自从引入词法范围以来,它很快就变得普遍,现在与其他任何东西一样得到了优化。

在这一点上,你可能会想,只要错误不是 提高性能不应受到影响。这是一个公平的 假设,但你错了。一些 JavaScript 引擎,例如 V8 (Chrome) 不优化使用 / 块的功能 因为优化编译器在遇到时会跳过它。不管怎样 在什么上下文中使用 / 块,总会有一个 固有性能受到打击,很可能是实质性的。trycatchtrycatch

这有一定的道理,但随着 2017 年新的优化编译器的出现,这很快就过时了。