我想知道哪种情况有更多“开销”:
1)案例1:共享30个功能的500万个对象。每次调用函数时都会产生开销,因为需要执行 f.call(instance,arg1,arg2等)
//example code
function makeObject()
{
return { method1:func1,
method2:func2,
...
method30:func30 };
}
2)案例2:500万个对象,每个对象有30个函数(= 1.5亿个单独的函数实例)。每次调用函数时,都没有“路由开销”,但当然牺牲了更多实例
//example code
function makeObject()
{
return { method1:func1.bind(asd),
method2:func2.bind(asd),
...
method30:func30.bind(asd) };
}
500万只是我手指输入的一个数字,而我的大脑仍在为一个例子找出一个不错的数字。
基本上我想知道我们应该尽可能分享功能还是创建新功能?
(你可以假设我永远不会在整个页面的任何地方使用eval函数)
答案 0 :(得分:5)
由于几乎所有现代浏览器都会优化prototype-
和scopeschain
查找,因此您绝对应该分享方法。
用简单的单词描述的优化技术是一种hash lookup table
,javascript引擎用来从out of scope
变量访问属性/方法。因此,与经典scope chain lookup
进行比较的开销非常小,其中引擎必须遍历每个父范围变量/激活对象。
如果存在某种直接lookup
'ed代码,则此优化eval
只会失败。由于eval
可以从上下文中更改属性,因此引擎必须回退到经典的查找算法(这有点慢)。
然而,对于Javascript引擎来说,500万个对象是不真实的,我希望这些数字只是一些例子。在现实世界中,调用n
个函数的5m对象会在周围创建堆栈溢出和“运行时间过长”错误。
单独parsing time
的1.5亿个功能将是不光彩的。
答案 1 :(得分:1)
如果假设案例2是关于创建类似于此的对象:
function makeObject()
{
return { method1:func1,
method2:func2,
...
method30:func30 };
}
然后你将拥有5米长的30个属性的对象。不是“1.5亿个人功能实例”。函数实例数仍为30。
要创建5米这样的对象会花费你一些东西。添加属性比阅读它要贵3到10倍。这意味着创建此类集可能比使用__proto__
使用一级间接寻址访问方法花费的时间更多。
简而言之:对于5m / 30,情况1在大多数情况下更为理想。但有些情况下,将方法引用放入对象本身是值得考虑的。例如。经常访问的对象/方法的数量有限(例如单身)。
答案 2 :(得分:1)
为什么不这样呢? :
function myObject() { }
myObject.prototype.method1 = func1
myObject.prototype.method2 = func2,
...
myObject.prototype.method30 = func30
因此,如果您将对象创建为
var obj = new myObject();
然后你将其方法称为:
obj.method1();
obj.method2();
不需要call()
和其他魔法......
在这种情况下,您不需要使用相同的30个属性填充对象的每个实例。