在firefox中,以下两个功能之间似乎有很大的性能差异:
var n1 = 12; var add1 = function(n2){ return n1 + n2; } var add2 = (function(){ return function(n2){ return n1 + n2; } })();
我认为这必须是引入另一个级别的范围,所以创建了第三个例子,缓存一个级别变量.
但这显示出更大的降低(80%!)
var add3 = (function(){ var cn1 = n1; return function(n2){ return cn1 + n2; } })();
我会认为这里的关闭会缩小业绩差距,而不是放大.有人有这个想法吗?
jsPerf测试页:http://jsperf.com/variable-scope-speed
解决方法
这很有趣,但是我的小测试似乎证实了我以前的假设,也就是说,jsPerf环境本身就会影响范围和范围链查询.我没有深入“如何”和“为什么”,但这是我的小测验脚本:
var n1 = 12; var add1 = function(n2){ return n1 + n2; } var add2 = (function(){ return function(n2){ return n1 + n2; } })(); var add3 = (function(){ var cn1 = n1; return function(n2){ return cn1 + n2; } })(); var add4 = function( n2,n1 ) { return n2 + n1; }.bind(null,n1); var tests = [add1,add2,add3,add4],start,stop,loops; tests.forEach(function( fnc ) { loops = 100000; start = Date.now(); while( loops-- ) { fnc( 2 ); } stop = Date.now(); console.info('Method ',fnc.name || fnc.toString(),': ',stop - start,' ms.'); });
而FireFox 14的结果如下所示:
Method add1: 570ms.
Method add2: 566ms.
Method add3: 414ms.
Method add4: 479ms.
最新的Chrome结果:
Method add1: 199ms.
Method add2: 136ms.
Method add3: 85ms.
Method add4: 144ms.
哪个看起来更合理.关闭的范围链查找必须总是更快,只是因为有一个较短的查找链.即使所有现代浏览器通常都不经常执行经典的范围链查找,我也知道.无论如何,由于浏览器为免费(或超出范围)变量创建漂亮的查找表,所有结果应至少是相同的.过度优化全球对象访问IMO没有任何意义.
你注意到,我为一个绑定的方法创建了一个附加的测试用例.