最小化作用域链的长度会提高性能吗?
Does minimizing the length of the scope chain improve performance?
背景
我经常使用模块模式来组织我的代码,以便函数和常量在需要知道的基础上运行。如果CONSTANT
或someFunc
只被anotherFunc
使用,那么我把anotherFunc
的定义封装在一个匿名函数中,这样前两者就不会污染全局作用域.这有助于避免名称冲突,还可以让您在稍后查看代码时确定什么取决于什么。
虽然这种策略确实创建了许多闭包,但我想知道显式传递这些依赖项是否会提高性能(并且更易于维护)。我认为这具有最小化函数必须遍历以查找变量的作用域链的效果。
为了允许对模块模式本身的反馈,我提供了三个版本:1) 没有模块模式,2) 有模块模式,3) 有模块模式和范围链最小化。
无模块模式
var SHARED_CONSTANT;
var SOME_CONSTANT = 5;
var INNER_CONSTANT = {};
var inner = function(y) {
return y !== {};
};
var outer = function g (x) {
doSomething();
$(...).load(inner);
};
有模块模式,但没有作用域链最小化
var SHARED_CONSTANT;
var outer = (function() {
var SOME_CONSTANT = 5;
var inner = (function() {
var INNER_CONSTANT = {};
return function /* inner */ (y) {
return y !== {};
};
}());
return function /* outer */ (x) {
doSomething();
$(...).load(inner);
};
}());
具有模块模式和作用域链最小化
var SHARED_CONSTANT;
var outer = (function($, SHARED_CONSTANT) {
var SOME_CONSTANT = 5;
var inner = (function(SOME_CONSTANT, SHARED_CONSTANT) {
var INNER_CONSTANT = {};
return function /* inner */ (y) {
return y !== {};
};
}(SOME_CONSTANT, SHARED_CONSTANT));
return function /* outer */ (x) {
doSomething();
$(...).load(inner);
};
}(jQuery, SHARED_CONSTANT));
总结
哪个版本应该有更好的性能(为什么)?性能差异是否显着? (即范围链查找很昂贵吗?)内存使用情况如何? (即通过传入变量,我实际上是在复制作用域,对吧?)
这些performance tests seem to confirm what I suggested。这是过早的优化。
测试没有显示任何明确的收藏夹。对于任何给定的浏览器,您的三个片段彼此接近,最快的一个变化次数最多,我 运行 它。在某些运行中,过度优化的代码甚至更慢。
可能是因为 JIT 优化。
要学习的教训: 尽可能保持代码的可读性,并担心在已知存在瓶颈的地方进行优化。
背景
我经常使用模块模式来组织我的代码,以便函数和常量在需要知道的基础上运行。如果CONSTANT
或someFunc
只被anotherFunc
使用,那么我把anotherFunc
的定义封装在一个匿名函数中,这样前两者就不会污染全局作用域.这有助于避免名称冲突,还可以让您在稍后查看代码时确定什么取决于什么。
虽然这种策略确实创建了许多闭包,但我想知道显式传递这些依赖项是否会提高性能(并且更易于维护)。我认为这具有最小化函数必须遍历以查找变量的作用域链的效果。
为了允许对模块模式本身的反馈,我提供了三个版本:1) 没有模块模式,2) 有模块模式,3) 有模块模式和范围链最小化。
无模块模式
var SHARED_CONSTANT;
var SOME_CONSTANT = 5;
var INNER_CONSTANT = {};
var inner = function(y) {
return y !== {};
};
var outer = function g (x) {
doSomething();
$(...).load(inner);
};
有模块模式,但没有作用域链最小化
var SHARED_CONSTANT;
var outer = (function() {
var SOME_CONSTANT = 5;
var inner = (function() {
var INNER_CONSTANT = {};
return function /* inner */ (y) {
return y !== {};
};
}());
return function /* outer */ (x) {
doSomething();
$(...).load(inner);
};
}());
具有模块模式和作用域链最小化
var SHARED_CONSTANT;
var outer = (function($, SHARED_CONSTANT) {
var SOME_CONSTANT = 5;
var inner = (function(SOME_CONSTANT, SHARED_CONSTANT) {
var INNER_CONSTANT = {};
return function /* inner */ (y) {
return y !== {};
};
}(SOME_CONSTANT, SHARED_CONSTANT));
return function /* outer */ (x) {
doSomething();
$(...).load(inner);
};
}(jQuery, SHARED_CONSTANT));
总结
哪个版本应该有更好的性能(为什么)?性能差异是否显着? (即范围链查找很昂贵吗?)内存使用情况如何? (即通过传入变量,我实际上是在复制作用域,对吧?)
这些performance tests seem to confirm what I suggested。这是过早的优化。
测试没有显示任何明确的收藏夹。对于任何给定的浏览器,您的三个片段彼此接近,最快的一个变化次数最多,我 运行 它。在某些运行中,过度优化的代码甚至更慢。
可能是因为 JIT 优化。
要学习的教训: 尽可能保持代码的可读性,并担心在已知存在瓶颈的地方进行优化。