减少这个JS程序的资源占用?

问题描述 投票:0回答:1

我写了以下JS程序,我在命令行使用node运行。

//step one: create an array of remaining creatures
var remainingCreatures = [];

//some config variables:
var amt = 1000; //amount of creatues generated
var maxhlt = 1000; //max value for creature health stat
var minhlt = 100; //min value for creature health stat
var maxatk = 100; //max value for creature attack stat
var minatk = 1; //min value for creature attack stat

function remove(target) { //helper function to easily remove creatues from the array
  var index = remainingCreatures.indexOf(target);
if (index > -1) {
  remainingCreatures.splice(index, 1);
}

}

//generate creatures
//each creature has an Attack, Health, and Aggressiveness , as well as Instabillity, the average of the three
//A creature's Instabillity is added to the attack points of its opponent in fights.
for (var i = 0; i < amt; i++) {
  var atkVal = Math.floor((Math.random() * maxatk) + minatk);
  var hltVal = Math.floor((Math.random() * maxhlt) + minhlt);
  var insVal = (atkVal + hltVal) / 2;

  remainingCreatures[i] = {num: i, atk: atkVal, hlt: hltVal, ins: insVal, fts: 0, ihlt: hltVal};
}
console.log(amt + " creatues generated, starting melee...");



function fight(cr1, cr2) { //function to handle fighting, randomly creates creature pairs and has them fight
  function attack(a, b) {
         console.log("[ROUND 1] Creature 1 (#" + a.num + ") is attacking first.");
    b.hlt = b.hlt - (a.atk + b.ins);
    console.log("[HIT] Creature #" + b.num + " health reduced to " + b.hlt);
    if (b.hlt <= 0) {
      console.log("[DEATH] Creature #" + b.num + " Eliminated");
      remove(b);
    } else {
      console.log("[ROUND 2] Creature 2 (#" + b.num + ") is attacking second.");
      a.hlt = a.hlt - (b.atk + a.ins);
      console.log("[HIT] Creature #" + a.num + " health reduced to " + a.hlt);
      if (a.hlt <= 0) {
      console.log("[DEATH] Creature #" + a.num + " Eliminated");
      remove(a);
    }
    }
  }
  console.log("[FIGHT] Pair generated: Creature #" + cr1.num + " and Creature #" + cr2.num);
  cr1.fts++;
  cr2.fts++;
   if (cr1.ins <= cr2.ins) {
    attack(cr1, cr2);
   } else {
    attack(cr2, cr1);
   }
}


for(;true;) {
  if(remainingCreatures.length == 1) break;
  fight(remainingCreatures[Math.floor(Math.random() * remainingCreatures.length)], remainingCreatures[Math.floor(Math.random() * remainingCreatures.length)]);
}

console.log(" ");
console.log("[WIN] Creature #" + remainingCreatures[0].num + " has won!");
console.log("Starting array size was " + amt + " creatures")
console.log(remainingCreatures[0]);

不知道为什么,这个程序开始变慢,并最终在以下情况下窒息。amt 被设置为非常大的数字,比如一百万。作为参考,这就是将生成并添加到数组中的对象数量--你可能在代码中看到,这个数组被循环了很多次。但即使有100万个对象,每个对象最大也只有80字节左右。而且这个程序所做的计算是非常基本的。

所以我的问题是:为什么运行这个程序会如此耗费资源,如何在不对程序功能进行太大改动的情况下,解决或缓解这个问题?

javascript arrays node.js resources resource-management
1个回答
0
投票

首先,一百万的任何东西都会对性能造成影响,无论多小.另一个问题是你的设计本质上是低效的。

看看你的 remove() 函数。它首先找到元素的索引,然后将其删除。如果你的数组中有一百万个元素,平均来说,它需要将传递的值与 500,000要素 只是为了在删除之前找到它。有一个简单的方法可以解决这个问题;直接传递索引,而不是使用 .indexOf.

function fight(ind1, ind2) { //function to handle fighting, randomly creates creature pairs and has them fight
  var cr1 = remainingCreatures[ind1];
  var cr2 = remainingCreatures[ind2];
  function attack(a, b) {
         console.log("[ROUND 1] Creature 1 (#" + a.num + ") is attacking first.");
    b.hlt = b.hlt - (a.atk + b.ins);
    console.log("[HIT] Creature #" + b.num + " health reduced to " + b.hlt);
    if (b.hlt <= 0) {
      console.log("[DEATH] Creature #" + b.num + " Eliminated");
      remove(ind2);
    } else {
      console.log("[ROUND 2] Creature 2 (#" + b.num + ") is attacking second.");
      a.hlt = a.hlt - (b.atk + a.ins);
      console.log("[HIT] Creature #" + a.num + " health reduced to " + a.hlt);
      if (a.hlt <= 0) {
      console.log("[DEATH] Creature #" + a.num + " Eliminated");
      remove(ind1);
    }
    }
  }
  console.log("[FIGHT] Pair generated: Creature #" + cr1.num + " and Creature #" + cr2.num);
  cr1.fts++;
  cr2.fts++;
   if (cr1.ins <= cr2.ins) {
    attack(cr1, cr2);
   } else {
    attack(cr2, cr1);
   }
}


for(;true;) {
  if(remainingCreatures.length == 1) break;
  fight(Math.floor(Math.random() * remainingCreatures.length), Math.floor(Math.random() * remainingCreatures.length));
}

虽然没有太多其他的方法可以轻松提高性能,但仅此一点就足够了。为了让你的代码更易读,可以考虑将这个。

for(;true;) {
  if(remainingCreatures.length == 1) break;
    fight(Math.floor(Math.random() * remainingCreatures.length), Math.floor(Math.random() * remainingCreatures.length));
}

换成这样。

// Consider using === and !== as best practice, but not necessary here
while (remainingCreatures.length != 1)
    fight(Math.floor(Math.random() * remainingCreatures.length), Math.floor(Math.random() * remainingCreatures.length));

(见此链接 关于该评论的信息)。)

© www.soinside.com 2019 - 2024. All rights reserved.