javascript - 为什么 JavaScript 中调用函数这么慢?

标签 javascript performance

我最近注意到了一些非常奇怪的事情:调用函数似乎比内部函数花费的时间要长得多。如this fiddle :

jQuery('button').click(function(){
    console.time('outer')
    dostuff.call(this)    
    console.timeEnd('outer')
})

dostuff = function(){
 console.time('inner')
 jQuery(this).css('background','red')
 jQuery(this).css('border','solid black')
 jQuery(this).css('margin','0 5px 0')
 jQuery(this).css('padding','0px')
 console.timeEnd('inner')
}

控制台输出显示外部比函数的实际工作慢得多...为什么会发生这种情况,更重要的是,如何在时间关键的代码中减少这个时间?

outer: timer started show:23
17:12:49.020 inner: timer started show:29
17:12:49.021 inner: 1.8ms show:34
17:12:49.023 outer: 5.1ms show:25
17:12:51.368 outer: timer started show:23
17:12:51.368 inner: timer started show:29
17:12:51.370 inner: 1.2ms show:34
17:12:51.370 outer: 2.47ms show:25
17:12:54.094 outer: timer started show:23
17:12:54.095 inner: timer started show:29
17:12:54.096 inner: 1.92ms show:34
17:12:54.098 outer: 3.67ms

最佳答案

微观基准测试可能非常具有误导性,这就是为什么它们通常不被鼓励的原因。为了正确地衡量任何事情的时间安排,您通常需要做足够多的有意义的工作(会产生副作用的工作,而不是临时计算某些东西然后丢弃它的工作)。否则,您将开始关注更多动态因素(缓存、分页、单个分支错误预测等)的时间。

您的问题有点过于宽泛,因为准确回答它需要准确了解所使用的精确 JavaScript 引擎的内部结构。我们必须知道编译器发出的确切反汇编代码以及何时发出,可以肯定地说。不过,如果您说明正在使用的确切 JavaScript 引擎,可能会帮助您获得更准确的答案。

也就是说,如果您使用 JIT,您可能已经知道,即时编译器会即时翻译指令(转换为字节码 IR 或直接转换为机器代码)。

其中一些是根据每个功能进行翻译的。如果是这种情况,您会发现首次函数调用的初始开销比后续调用要昂贵得多,因为您要支付 JIT 遇到的新代码的“首次遇到”开销。

如果您使用跟踪 JIT,那么 JIT 将分析执行的常见情况分支(“热路径”),并且您同样可以在跟踪代码路径中看到一种“首次遇到”开销,直到出现常见情况为止。 case 执行分支已建立。

无论如何,所有这些都是假设的,但值得注意的是,对于许多 JIT,代码的首次执行在性能上存在显着偏差(比相同代码的后续执行要昂贵得多)。这可能可以解释您的结果,也可能不能。

但无论情况如何,您通常都希望避开微基准,尤其是涉及越来越多的动态因素(脚本语言比 native 代码添加了更多内容)。如今,我们使用非常复杂的硬件和编译器,它们试图为我们预测事情,在动态编译代码的情况下,除了硬件和操作系统之外,我们还有另一个元素可以动态地进行预测。当我们开始在太细粒度的水平上测量事物时,再加上这些动态因素,我们就不再测量代码的速度,而是开始对这些动态因素进行逆向工程。

关于javascript - 为什么 JavaScript 中调用函数这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30721101/

相关文章:

javascript - 道场验证

performance - 文件大小如何影响性能?

javascript - 减去两个 HH :MM strings with a recursive function

javascript - JavaScript 生成器中yield 返回值的解析

条件与划分

performance - VBA屏幕更新和效率

ios - iOS 移动应用程序性能测试最好用哪个工具

java - 适当的 Tomcat 5.5 启动参数来调整 JVM 以满足极高的需求、大堆 Web 应用程序?

javascript - 内联 Babel 脚本 : Unexpected token

javascript - 无法分配给对象的只读属性