PHP-重复的操作变得越来越慢

PHP-重复的操作变得越来越慢,php,Php,我有一个PHP脚本,它可以创建一个树,其中包含一个游戏的所有可能动作,最多可以提前15步 创建移动的脚本如下所示: function createPossibleMoves($heroId, Hero $Hero, Move $LastPossibleMove = null) { $moves = array(); foreach ($Hero->Attacks as $attackid => $attack) { if ($attack['uses']

我有一个PHP脚本,它可以创建一个树,其中包含一个游戏的所有可能动作,最多可以提前15步

创建移动的脚本如下所示:

function createPossibleMoves($heroId, Hero $Hero, Move $LastPossibleMove = null) {    
 $moves = array();
 foreach ($Hero->Attacks as $attackid => $attack) {
        if ($attack['uses'] < 1) continue;
        $usesLeft = $attack['uses'];

        $LastPerformedMoveIterator = $LastPerformedMove;
        while (is_a($LastPerformedMoveIterator, "Move")) {
            if ($LastPerformedMoveIterator->heroId == $heroid && $LastPerformedMoveIterator->attackId == $attackid) $usesLeft--;
            $LastPerformedMoveIterator = $LastPerformedMoveIterator->PreviousMove;  
        }

        if ($usesLeft < 1) continue;

        if ($attack['targets'] === 1) {
            foreach ($this->Monsters as $monsterid=>$Monster) {
                $Move = new Move($heroid, $attackid, $this, array($monsterid));
                $Move->setPreviousMove($LastPerformedMove);
                $moves[$Move->getMoveHash()] = $Move;
            }
        } else {
            $maxTargets = $attack['targets'];
            if ($maxTargets > count($this->Monsters)) $maxTargets = count($this->Monsters);
            $combinations = new Combinations($this->getMonsterIds(), $maxTargets);
            foreach ($combinations as $combination) {
                $Move = new Move($heroid, $attackid, $this, $combination);
                $Move->setPreviousMove($LastPerformedMove);
                $moves[$Move->getMoveHash()] = $Move;
            }
        }
    }
}
public function __construct($heroId, $attackId, Battlefield $Battlefield, $targets) {
    $this->Battlefield = clone $Battlefield;
    $this->PreviousBattlefield = $Battlefield;

    $this->Hero = $this->Battlefield->getHero($heroId);
    $this->heroId = $heroId;

    $this->attackId = $attackId;
    $this->Attack = $this->Hero->getAttack($attackId);


    foreach ($targets as $monsterId) {
        $this->Targets[] = $this->Battlefield->getMonster($monsterId);
    }
    $this->targetList = $targets;
}
battle
类保存执行动作的战场的单一状态,包括所有
怪物
实例和所有
英雄
实例。当一个
战场
被克隆时,它的每个
怪物
实例和
英雄
实例也被克隆

我注意到,当我尝试使用
createPossibleMoves
函数创建大约6000-7000个
Move
实例时,一开始,一个
Move
实例会在大约0.0005秒内创建,但到最后,这个数量会上升到惊人的0.1秒/
Move
实例


时间突然跳跃的原因可能是什么?我尝试为这个PHP脚本提供更多内存,但对这种情况没有帮助。

下面的解决方案是尝试取消设置变量,并每1000次移动计算显式调用垃圾收集

这会将您的查询速度降低到5000以下,但应该会提高到5000以上,尽管因为您没有提供完整的父类和Hero and Move类,所以我无法测试此解决方案

PS:看在上帝的份上,请评论你的代码,这样任何观察者都能很快理解你的逻辑意图

函数createPossibleMoves($herod,Hero$Hero,Move$LastPossibleMove=null){
$moves=array();
foreach($Hero->攻击为$attackid=>$attack){
如果($attack['uses']<1)继续;
$usesLeft=$attack['uses'];
$LastPerformedMoveIterator=$LastPerformedMove;
while(是($LastPerformedMoveIterator,“Move”)){
如果($LastPerformedMoveIterator->heroId=$heroId&$LastPerformedMoveIterator->attackId==$attackId)$usesLeft--;
$LastPerformedMoveIterator=$LastPerformedMoveIterator->PreviousMove;
}
如果($usesLeft<1)继续;
如果($attack['targets']==1){
foreach($this->Monsters as$monsterid=>$Monster){
$Move=newmove($hergod,$attackid,$this,array($monsterid));
$Move->setPreviousMove($LastPerformedMove);
$moves[$Move->getMoveHash()]=$Move;
}
}否则{
$maxTargets=$attack['targets'];
如果($maxTargets>count($this->Monsters))$maxTargets=count($this->Monsters);
$combinations=新组合($this->getMonsterIds(),$maxTargets);
foreach($组合为$组合){
$Move=新移动($hergod,$attackid,$this,$combination);
$Move->setPreviousMove($LastPerformedMove);
$moves[$Move->getMoveHash()]=$Move;
}
}
//未结算$Move
取消设置($Move)
//每1000次移动显式调用垃圾收集
如果(计数($moves)%1000==0)gc_collect_cycles();
}
}

@WillardSolutions我的问题确实是为什么6000-7000内存对象会使PHP变慢。我的问题是,这么少的内存对象会让PHP这么慢吗?如果是,有什么帮助?使用简单数组而不是对象会加快速度吗?我不确定,但内存中的6.000或7.000对象并不会使PHP变慢,但6.000-7.000项的for循环会使PHP变慢。@Osakr是的,但问题是,对于如此多的循环,并不是整个函数都变慢,随着时间的推移,循环的单个迭代越来越慢。您能否更详细地解释一下
while
循环的作用?您能否准确地确定在以后的迭代中哪些代码段变慢了,以及速度是如何降低的?它是逐渐变慢的,还是在某个点跳跃?我怀疑问题可能是内存分配(垃圾收集器)或类似的问题,例如耗尽磁盘写缓存