call和apply的性能比较

call和apply

性能比较

关于它们性能上的问题我还是在看backbone的源码时知道的,先附上backbone关于它们的源码:

var triggerEvents = function(events, args) {
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    switch (args.length) {
      //赋值操作和调用方法合写
      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
    }
};

可以看到,传递的参数不超过3个则使用call,超过了3个则使用apply。

瞬间感觉又长姿势了,为了加深印象,我对这两货进行了性能测试。有图有真相,要不然我逼逼谁信呢?

无参数

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
suite.add('apply', function(){
	a();
}).add('call', function(){
	b();
}).on('cycle', function(event){
	console.log(String(event.target));
}).on('complete', function(){
	console.log('最快的是:'+this.filter('fastest').map('name'));
}).run({
	async: true
});
function a(){
	var obj = {name:'a'};
	function say(){}
	say.apply(obj);
}
function b(){
	var obj = {name:'b'};
	function say(){}
	say.call(obj);
}

apply x 23,847,355 ops/sec ±1.02% (86 runs sampled)
call x 27,034,022 ops/sec ±0.90% (82 runs sampled)
最快的是:call

一个参数

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
suite.add('apply', function(){
	a(1);
}).add('call', function(){
	b(1);
}).on('cycle', function(event){
	console.log(String(event.target));
}).on('complete', function(){
	console.log('最快的是:'+this.filter('fastest').map('name'));
}).run({
	async: true
});
function a(p){
	var obj = {name:'a'};
	function say(p){		
	}
	say.apply(obj,arguments);
}
function b(p){
	var obj = {name:'b'};
	function say(p){	
	}
	say.call(obj,p);
}

apply x 20,431,609 ops/sec ±0.72% (85 runs sampled)
call x 26,801,504 ops/sec ±0.88% (85 runs sampled)
最快的是:call

两个参数

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
suite.add('apply', function(){
	a(1);
}).add('call', function(){
	b(1);
}).on('cycle', function(event){
	console.log(String(event.target));
}).on('complete', function(){
	console.log('最快的是:'+this.filter('fastest').map('name'));
}).run({
	async: true
});
function a(p1,p2){
	var obj = {name:'a'};
	function say(p1,p2){}
	say.apply(obj,arguments);
}
function b(p1,p2){
	var obj = {name:'b'};
	function say(p1,p2){}
	say.call(obj,p1,p2);
}

apply x 16,572,150 ops/sec ±1.90% (81 runs sampled)
call x 24,683,569 ops/sec ±1.13% (82 runs sampled)
最快的是:call

四个参数

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
suite.add('apply', function(){
	a(1,2,3,4);
}).add('call', function(){
	b(1,2,3,4);
}).on('cycle', function(event){
	console.log(String(event.target));
}).on('complete', function(){
	console.log('最快的是:'+this.filter('fastest').map('name'));
}).run({
	async: true
});
function a(p1,p2,p3,p4){
	var obj = {name:'a'};
	function say(p1,p2,p3){}
	say.apply(obj,arguments);
}
function b(p1,p2,p3,p4){
	var obj = {name:'b'};
	function say(p1,p2,p3,p4){}
	say.call(obj,p1,p2,p3,p4);
}

apply x 16,709,388 ops/sec ±0.73% (87 runs sampled)
call x 25,625,382 ops/sec ±1.15% (84 runs sampled)
最快的是:call

最结论可以看到,call的性能是远高于apply的,不管传的参数有几个。那为什么backbone要这么搞?参数的数量我们无法控制,如果调用call,难道我们要写无限个call吗,当然不会,一个apply就可以包含所有的参数,虽然性能上略有下降,但是书写上却要省事许多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值