有没有比使用 if-else 语句更快/更有效的方法调用不同的函数,具体取决于变量的值范围?



作为我正在制作的小游戏的一部分,我有一个 enemy对象,该对象向播放器控制的 character对象发射弹丸。enemy具有具有10000值的hp属性,并且随着此值的耗尽,我希望更改弹丸射击模式。这是我目前的情况:

this.fireOnce = function(){ ... }
this.fireRandomly = function(){ ... }
this.fireAtTarget = function(){ ... }
this.fireWave = function(){ ... }
this.beginFire = function(){
    if(hp<3000){
        this.fireWave();
    }
    else if(hp<5000){
        this.fireAtTarget();
    }
    else if(hp<9000){
        this.fireRandomly();
    }
    else{
        this.fireOnce();
    }
    setTimeout(beginFire, 500);
}

主循环已经具有足够的复杂性,当许多弹丸在屏幕上时,事情变得越来越懒。我对IF-Else陈述的担忧来自我的教授所说的关于它们相当昂贵的话(尽管我不记得背景,所以我可能错了(。

在创建这个小游戏期间,我已经多次使用了上述结构来进行不同的问题,并且考虑到每个功能每秒都被调用多次,我认为它会损害游戏的性能。

另一种情况下的一种可能性是使用包含功能的对象,但是由于我们谈论的是整数范围,所以我想不出要用作钥匙的东西。

"相当昂贵"是一个相对术语。是的,有条件的分支,如果未预测条件的值,则很容易花费数十个时钟周期,这意味着单个CPU只能执行每秒数百万个IF语句。

要验证这一点,请在目标的Java脚本运行时运行以下脚本:

let odd = 0;
for (let i = 0; i < 1000000000; i++) {
    if (i % 2) odd++;
}
odd;    

该代码执行十亿个if语句。在Chrome中,我的机器大约需要3秒钟。Firefox速度较慢,但仍执行100万if IF命令在大约0.2秒内,即在0.1秒内陈述100万。

得出结论,没有现代的JavaScript运行时,其中一些IF语句每秒会导致可衡量的,更不用说人类可察觉的性能降解了。无论您的性能问题的根源是什么,这都不是您对语句的使用。

您应该始终提防预先优化,但是您可能希望使代码更清楚一些(尽管OP没有错(。如果可以减少逻辑以生成单个值,则可以创建更多简洁的代码,然后将该值用作调用方法的键。

例如。如果断点为3000、6000和9000,则可以从hp / 3000派生:

function Bot(){
  // sorted by value
  this.fireWave = function(){     // hp <= 3000
    console.log('fireWave');
  }
  this.fireAtTarget = function(){ // hp <= 6000
    console.log('fireAtTarget');
  }
  this.fireRandomly = function(){ // hp <= 9000
    console.log('fireRandomly');
  }
  this.fireOnce = function(){     // hp > 9000
    console.log('fireOnce');
  }
    
  // Method names in order
  var methods = ['fireOnce','fireWave','fireAtTarget','fireRandomly'];
    
  this.beginFire = function(){
    this[methods[Math.ceil(hp / 3000)] || methods[0]]();
    // Don't do this for testing
    // setTimeout(beginFire, 500);
  }
}
var bot = new Bot();
var hp = 0;
for (var i=0; i<10; i++) {
  // Randomly set hp to value between 0 and 1200
  hp = Math.random()*12000 | 0;
  console.log('hp: ' + hp);
  bot.beginFire();
}

,只要您可以确定一个简单的数学表达式来计算代码,就可以轻松确定调用的方法。

function getFireMethod() {
  return hp < 3000? 'fireWave' :
         hp < 5000? 'fireAtTarget' :
         hp < 9000? 'fireRandomly' : 
                    'fireOnce';
}

这是清晰而简洁的,但同时又可能不会对性能产生任何明显的影响。

无论如何,您都需要在各种客户端进行测试,以确定是否有任何有用的绩效增益。另外,在代码中包括评论以描述逻辑。

最新更新