Javascript 函数声明和函数表达式性能差异

Javascript 函数声明和函数表达式性能差异,javascript,function,jsperf,function-expression,Javascript,Function,Jsperf,Function Expression,我曾经测试过一个小样本 根据我遇到的几篇文章,两者的性能应该相似,test2有一点优势。但在这里,情况完全相反。有人能解释为什么会有如此巨大的差异吗 编辑:我也理解两者之间的区别。请不要将此标记为重复或其他讨论语义差异的问题,也不要回答我有关性能的问题 谢谢。随着JavaScript引擎目前使用的强大优化,像这样的微型基准测试会产生一些误导性的结果。例如,我猜您试图测量的是函数调用开销。但它看起来像是您的代码编写方式,您可能每执行10次就重新定义函数定义和/或符号查找一次;我猜这不是目的 在中,

我曾经测试过一个小样本

根据我遇到的几篇文章,两者的性能应该相似,test2有一点优势。但在这里,情况完全相反。有人能解释为什么会有如此巨大的差异吗

编辑:我也理解两者之间的区别。请不要将此标记为重复或其他讨论语义差异的问题,也不要回答我有关性能的问题


谢谢。

随着JavaScript引擎目前使用的强大优化,像这样的微型基准测试会产生一些误导性的结果。例如,我猜您试图测量的是函数调用开销。但它看起来像是您的代码编写方式,您可能每执行10次就重新定义函数定义和/或符号查找一次;我猜这不是目的

在中,我安排了一些事情来避免重复定义函数,并添加了一些调用函数的其他方法。这减少了性能差异,我认为占主导地位的实验噪音。虽然这可能有时有明显的差异,但我不认为它们的统计意义重大的实验误差水平。换句话说,它将比赛缩小为一场虚拟的平局


即使在不同方法之间存在一致差异的浏览器中,将函数缓存在局部变量中似乎也能最大限度地减少定义和表达式之间的差异。

随着JavaScript引擎目前使用的强大优化,类似这样的微基准测试会产生一些误导性的结果。例如,我猜您试图测量的是函数调用开销。但它看起来像是您的代码编写方式,您可能每执行10次就重新定义函数定义和/或符号查找一次;我猜这不是目的

在中,我安排了一些事情来避免重复定义函数,并添加了一些调用函数的其他方法。这减少了性能差异,我认为占主导地位的实验噪音。虽然这可能有时有明显的差异,但我不认为它们的统计意义重大的实验误差水平。换句话说,它将比赛缩小为一场虚拟的平局

即使在不同方法之间存在一致差异的浏览器中,将函数缓存在局部变量中似乎也可以最小化定义和表达式之间的差异

我也理解两者之间的区别

你也明白吗

请注意,jsPerf将代码放入一个紧循环中,该循环的执行时间是经过测量的。函数声明需要为每个迭代创建一个块范围,这会大大降低测试速度。这并不是你想要衡量的

我也理解两者之间的区别

你也明白吗


请注意,jsPerf将代码放入一个紧循环中,该循环的执行时间是经过测量的。函数声明需要为每个迭代创建一个块范围,这会大大降低测试速度。这并不是你想要衡量的。

把我们和实际的测试用例联系起来怎么样?@Cerbrus添加了测试链接。不管谁投了反对票,你能给出原因吗?将有助于提出更好的问题可能是@Rajesh的复制品这些问题都是一样的。应该没有什么区别。但我在这里展示了不同之处。我不明白我的问题是怎么重复的。把我们和实际的测试用例联系起来怎么样?@Cerburs添加了测试链接谁投了反对票,你能给出原因吗?将有助于提出更好的问题可能是@Rajesh的复制品这些问题都是一样的。应该没有什么区别。但我在这里展示了不同之处。我不明白我的问题是怎么重复的。我同意。出于同样的原因,在微基准中,引擎之间的明显差异远远大于现实世界中的用例。jsPerf度量值中的1000个差异并不一定意味着对典型应用程序有任何意义。@Bergi“函数声明需要创建块范围”是什么意思?每个循环不都引入自己的块范围吗?或者你的意思是不包含声明的块作用域是“空”的,可以优化掉吗?@ie\m,我怀疑块作用域可以像写的那样优化掉,它包含被调用函数的函数定义。@Burt\u Harris刚刚编辑了上面的注释;我将只有var声明的循环体称为“空”范围。我理解Bergi答案的问题是“需要”——我对范围界定的理解是ra
因此,我很乐意了解更多信息。@le_m是的,当循环体中没有放置在作用域中的let、const或函数声明时,将不会创建它。这就是为什么具有块作用域变量的循环比不具有块作用域变量或函数作用域变量的循环更有效的原因——至少在当前的引擎中是如此。出于同样的原因,在微基准中,引擎之间的明显差异远远大于现实世界中的用例。jsPerf度量值中的1000个差异并不一定意味着对典型应用程序有任何意义。@Bergi“函数声明需要创建块范围”是什么意思?每个循环不都引入自己的块范围吗?或者你的意思是不包含声明的块作用域是“空”的,可以优化掉吗?@ie\m,我怀疑块作用域可以像写的那样优化掉,它包含被调用函数的函数定义。@Burt\u Harris刚刚编辑了上面的注释;我将只有var声明的循环体称为“空”范围。我理解Bergi答案的问题是术语“requires”-我对作用域的理解相当肤浅,因此我很乐意了解更多。@le_m是的,当循环体中没有放置在作用域中的let、const或函数声明时,将不会创建它。这就是为什么具有块作用域变量的循环比不具有块作用域变量或函数作用域变量的循环要好的原因——至少在当前的引擎中是这样。