【问题标题】:function declaration and function expression performance difference函数声明和函数表达式性能差异
【发布时间】:2017-05-17 11:25:02
【问题描述】:

我使用JSperf 测试了code 的小样本。

根据我遇到的几篇文章,两者应该具有相似的性能,而 test2 有一点优势。但这里完全相反。谁能解释一下为什么会有这么大的差异?

编辑:我也理解它们之间的区别。请不要将此标记为与this 或其他谈论语义差异的问题的重复,并且不要回答我关于性能的问题。

谢谢。

【问题讨论】:

标签: javascript function jsperf function-expression


【解决方案1】:

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

this alternative test 中,我已经安排了一些事情以避免重复定义函数,并添加了一些其他调用函数的方式。这将性能差异减少到我认为由实验噪声主导的东西。虽然这有时可能会有明显的差异,但考虑到实验误差水平,我不会认为它们具有统计学意义。换句话说,它将比赛减少为虚拟平局。

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

【讨论】:

    【解决方案2】:

    我也理解两者的区别。

    these semantic differences你也懂吗?

    请注意,jsPerf 将您的代码置于一个紧凑的循环中,该循环的执行时间会被测量。函数声明需要为每次迭代创建一个块作用域,这大大减慢了测试速度。这几乎不是你想要衡量的。

    【讨论】:

    • 同意。出于同样的原因,在微基准测试中 between 引擎的明显差异远大于实际用例。 jsPerf 测量值相差 1,000 倍并不一定意味着对典型应用程序有任何意义。
    • @Bergi “函数声明需要创建块作用域”是什么意思?不是每个循环都引入了自己的块范围吗?或者你的意思是没有声明的块作用域是“空的”并且可以被优化掉?
    • @ie_m,我怀疑块作用域可以像写的那样优化掉,它包含被调用函数的函数定义。
    • @Burt_Harris 刚刚编辑了上面的评论;我指的是只有 var 声明的循环体作为“空”范围。我理解 Bergi 的答案的问题是“需要”这个词——我对范围界定的理解相当肤浅,所以我很乐意了解更多。
    • @le_m 是的,当循环体中没有 letconstfunction 声明时,将不会被创建。这就是为什么带有块范围变量的循环是 running slower 而不是没有(或函数范围 vars)的循环的原因——至少在当前引擎中是这样。
    猜你喜欢
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 2015-03-11
    • 2014-05-31
    • 2016-06-18
    相关资源
    最近更新 更多