设置一个关键,如果没有设置 – 哪种方式是最有效的?
什么是最有效的方法来检查一个对象是否设置了一个键,如果没有,将其设置为一个给定的值? 请记住,这只适用于高性能的情况
让我们假设someCostlyOperation()
需要大量的CPU时间来计算,永远不会返回一个falsy值
方法#1
if(!myObj.myKey) myObj.myKey = someCostlyOperation();
方法#2
myObj.myKey = myObj.myKey || someCostlyOperation();
概要:
-
方法1检查myKey是否是虚假的。 如果
undefined
,则将其设置为someCostlyOperation()
。 -
方法#2没有条件,但总是重新分配
myObj.myKey
。 如果是麻痹的话,它会将其设置为someCostlyOperation()
。
性能上的差异可能并不明显,但是在对这条线进行数万次评估的嵌套循环中,每一个小的优化都很重要,以便缩短执行时间并提高整体应用程序的性能。
我假设方法#1更快,因为它使方法#2所做的对myObj.myKey
的检查相同,但是不会每次都无用地重新分配它。 我可能是错误的,因为我不知道所有的内部优化的JavaScript解释器使这样的代码(在我的情况下,它运行与Node.js)。
什么是完成这个最好的方法?
编辑
Arnauld在评论中提出了第三种方法。 这里是 :
方法#3
!myObj.myKey && (myObj.myKey = someCostlyOperation());
这基本上是所有3种方法之间的联系。
(function(){ var myObj = { }; var time1,time2,testTime1,testTime2,testTime3,test1Wins=0,test2Wins=0,test3Wins=0,noWinner=0; function someCostlyOperation(){ for(var i=0; i<100000; i++){ } return {}; } function method1(){ if(!myObj.myKey) myObj.myKey = someCostlyOperation(); } function method2(){ myObj.myKey = myObj.myKey || someCostlyOperation(); } function method3(){ !myObj.myKey && (myObj.myKey = someCostlyOperation()); } for(var i=0;i<10000;i++){ delete myObj.myKey; time1 = performance.now(); method3(); time2 = performance.now(); testTime1 = time2-time1; delete myObj.myKey; time1 = performance.now(); method2(); time2 = performance.now(); testTime2 = time2-time1; delete myObj.myKey; time1 = performance.now(); method3(); time2 = performance.now(); testTime3 = time2-time1; if(testTime1<testTime2 && testTime1<testTime3){ test1Wins++; } else if(testTime2<testTime3 && testTime2<testTime1){ test2Wins++; } else if(testTime3<testTime1 && testTime3<testTime2){ test3Wins++; } else{ noWinner++; } } console.log("test1Wins:",test1Wins); console.log("test2Wins:",test2Wins); console.log("test3Wins:",test3Wins); console.log("noWinners:",noWinner); })();