Javascript 性能:开关与多态性
如果可能的话,我通常更喜欢多态性而不是开关。我发现它可读性更强,需要的行更少。我相信这些事实足以继续使用它。但是性能呢?我已经创建了一个非常简单(而且很糟糕)的工作台,看起来在我的情况下切换速度更快。你能解释一下原因吗Javascript 性能:开关与多态性,javascript,switch-statement,polymorphism,v8,vtable,Javascript,Switch Statement,Polymorphism,V8,Vtable,如果可能的话,我通常更喜欢多态性而不是开关。我发现它可读性更强,需要的行更少。我相信这些事实足以继续使用它。但是性能呢?我已经创建了一个非常简单(而且很糟糕)的工作台,看起来在我的情况下切换速度更快。你能解释一下原因吗 var class1={GetImportantValue:()=>1}; var class2={GetImportantValue:()=>2}; var class3={GetImportantValue:()=>3}; var class4={GetImportantV
var class1={GetImportantValue:()=>1};
var class2={GetImportantValue:()=>2};
var class3={GetImportantValue:()=>3};
var class4={GetImportantValue:()=>4};
var class5={GetImportantValue:()=>5};
getImportantValueSwitch=(myClassEnum)=>{
开关(myClassEnum.type){
案例“MyClass1”:返回1;
案例“MyClass2”:返回2;
案例“MyClass3”:返回3;
案例“MyClass4”:返回4;
案例“MyClass5”:返回5;
}
}
GetImportantValue多态性=(myClass)=>myClass.GetImportantValue();
测试=()=>{
var交互计数=10000000;
var t0=performance.now();
对于(变量i=0;i
据我所知,第一个示例有一个动态/虚拟运行时调用myClass.GetImportantValue()
,就是这样。但是第二个也有一个动态/虚拟运行时调用myClassEnum.type
,然后检查开关中的条件
很可能代码中有一些错误,但我找不到。我认为唯一能影响结果的是性能。now()
。但我认为这不会有太大影响。我看不出你的脚本中有“错误”。虽然我真的不鼓励以这种方式进行性能测试,但根据我的直觉,我仍然可以说几句话。我对控制组等没有可靠的、经过良好测试的结果,所以我所说的一切都要小心谨慎
现在,对我来说,假设第一个选项会吃掉第二个选项的灰尘是很正常的,因为在js中有两件事情比变量访问更昂贵:
- 对象属性访问(可能是O(1)哈希表,但仍然比变量访问慢)
- 函数调用
- 第一种情况:5次调用[to
]x(1次对象访问[toGetImportantValue
]+1次函数调用[tomyClass
]===>总共10次函数调用+5次对象访问GetImportantValue
- 第二种情况:5次调用[to
]+5次对象访问[togetImportantValueSwitch
]===>总共5次函数调用+5次对象访问MyClassEnum
迭代计数减少到100000,即减少100倍,您将看到在chrome中,比率将从~20减少到~2。因此,底线1:您观察到的部分低效率来自于您正在饥饿事件循环的事实,但它仍然没有改变第一个选项的事实速度较慢
要测试函数调用是否确实是此处的瓶颈,请将脚本的相关部分更改为:
class1 = class1.GetImportantValue;
class2 = class2.GetImportantValue;
class3 = class3.GetImportantValue;
class4 = class4.GetImportantValue;
class5 = class5.GetImportantValue;
对于测试:
for (var i = 0; i < INTERATION_COUNT; i++) {
class1();
class2();
class3();
class4();
class5();
}
for(变量i=0;i
产生的小提琴:
这一次你会看到第一个更快,因为它是(5个函数调用)与(5个函数调用+5个对象访问)。V8开发者在这里。你的直觉是正确的:这个微基准不是很有用
一个问题是,所有的“类”都具有相同的形状,因此“多态”情况实际上是单态的(如果您解决了这个问题,请注意V8在=5个多态情况下具有截然不同的性能特征!)
一个问题是您依赖于堆栈替换(
for (var i = 0; i < INTERATION_COUNT; i++) {
class1();
class2();
class3();
class4();
class5();
}