【问题标题】:Are object methods faster than global functions? [closed]对象方法比全局函数快吗? [关闭]
【发布时间】:2012-10-15 09:04:34
【问题描述】:

问题

不敢相信我在网上找不到任何东西,也许我正在寻找错误的东西......

可能几乎没有区别,但由于我正在尽我所能优化我的代码,我觉得值得一问。

很简单,我想知道在对象中定义和运行方法是否比全局定义和运行函数更快。

示例

考虑一下:

(function($){  
    $.fn.test = function() {  
        // do something here
    };  
})(jQuery);

还有这个:

function test(){
    // do something here
}

我的问题

以上哪个更快,为什么?如果速度没有差异,那么您建议使用哪个?

提前致谢

更新 1

因为它可能是相关的,我觉得有必要解释我为什么要问这个问题。我有一个多年来编写的库,其中包含多种功能。由于它们太多,我想知道如果我要扩展 jQuery 对象,它们是否会运行得更快,或者保持原样?

【问题讨论】:

  • 对我来说,全局函数的开销会更少,因为没有要处理的对象。不过我可能完全错了:)
  • @JonTaylor 即使对象仍然存在?
  • 您是否尝试分析您的两个示例?例如,Chrome 为您提供了一个分析工具 (CTRL + SHIFT + I > Profiles)。分析并查看最适合您的情况。不要忘记在您的目标浏览器上进行测试。 IMO,我认为方法可以更快地调用,因为它们位于 smaller 命名空间中。全局函数位于全局命名空间中,您通常无法想象所有函数都存在于其中...
  • 回答 X 比 Y 更快的问题的最佳方法是测试自己。我建议 jsperf.com 跨浏览器测试它。只需设置它并使用多个浏览器运行。还请不同机器和 Op.Systems 上的朋友做同样的事情,瞧。
  • @BenCarey 检查此测试:jsperf.com/global-context-or-class-context/3(Chrome 17.0.963 + FF 10.0.2 + IE6)。使用 noop test() 函数,全局上下文显然“获胜”。

标签: javascript jquery oop optimization


【解决方案1】:

理论上,您只需要计算必须搜索的对象数量即可确定哪个更快。变量是根据作用域链解析的,脚本引擎必须首先搜索函数的执行上下文,然后是外部上下文,最后是全局上下文。

属性解析必须首先找到作用域链上的对象,然后是对象或其[[Prototype]]链上的属性。

但在实践中,编译器优化意味着上述简单化的分析是错误的,也是正确的,并且在不同的浏览器中针对不同的情况提供不同的结果。

通常,此类优化会带来微小的性能变化,不应仅出于性能原因考虑。为您的应用程序架构、易于维护和逻辑分组设计任何有意义的对象和方法。

【讨论】:

  • +1 表示最后一段。过早的优化往往是徒劳的。
  • +1 出色的回答,谢谢 :-) 我这样做的原因是为了逻辑分组,所以我想我可能只是扩展 jQuery 对象
  • @BenCarey 除非它们是 jQuery 插件,否则为什么不为这些函数创建自己的命名空间?
  • @Alnitak 是的,我知道,这就是我要做的。只是因为其中一些将是 jQuery 插件,而其中一些将是通用函数。我可能会将它们中的大部分添加到我自己的命名空间中:-)
【解决方案2】:

我大约一年前做过这项研究,我可以说使用this.test() 更快。

但这取决于你需要什么。如果您只想为特定的“小部件”创建一个对象,我不建议向 jQuery 添加不必要的函数。

简单的面向对象用法:

function Car(name) {
    this.name = name;
}

Car.prototype.startEngine = function() {
    // Start the engine...
};

Car.prototype.drive = function() {
    this.startEngine();

    // Switch the lights, fasten your seatbelt...
};


// create a new car
var bmw = new Car('BMW');

// Drive the car
bmw.drive();

你必须了解的另一件事是环境(我希望你明白我的意思)。最好为变量和函数创造一个新鲜的空间,这样就没有太多的变量/函数需要寻找。把它想象成一个列表——如果它更小,在其中找到东西会更快。 所以,你创造了一个新的“空间”:

(function(){
    // Your fresh space.
})();

JavaScript 将尝试在“本地”空间中查找内容,然后尝试在全局空间中查找内容。想象一下:

|- global
     |- function aaa
     |- function bbb
     |- var myName
     |- your local space
           |- function ccc
           |- function aaa  It will not overwrite global function with the same name
           |- var someVariable

如您所见,“本地空间”中只有 3 个项目,因此查找内容更快。

在本地“空间”中调用半全局函数更快。而且,如果你想做一些面向对象的事情,扩展“对象”会更好更快。

更新 如果你想整理你的函数库,那么你可以将它们分组到一个对象中。我不认为它会更慢。

var lib = {
    foo: function() {},
    bar: function() {},
    test: function() {}
};

lib.test();

【讨论】:

  • 将函数添加到构造函数对象的原型与将函数添加为对象的 properties 以用于命名空间的目的不同。
【解决方案3】:

当您想知道两种方法中哪一种更快时,最好的方法是分析它们。这将为您提供与您的代码相关的结果,而不是通用概念。

在我看来,您不应该为了速度而优化它,而是为了 API 的可维护性和丰富性。根据您的问题

function test(){
    // do something here
}

在全局范围内,这总是不好的。理想情况下,您应该将这些方法放在命名空间中,并且您问题中的示例 1 将其作为 jQuery 命名空间的一部分。

【讨论】:

  • +1 另一个好答案,谢谢
猜你喜欢
  • 2017-04-30
  • 2012-12-16
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
相关资源
最近更新 更多