Thursday, 10 January 2019

PHP - Repeated operations get slower and slower

I have a PHP script which creates a tree with all possible moves for a game up to 15 steps ahead.

The script that creates the moves looks something like this:

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;
            }
        }
    }
}

and the constructor for the Move class looks like this:

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;
}

The Battlefield class holds a single state of the Battlefield where the actions are performed, with all the Monster instances, and all the Hero instances. When a Battlefield is cloned, each of it's Monster instances and Hero instances are also cloned.

I've noticed that when I try to create around ~6000-7000 Move instances with the createPossibleMoves function, at the beginning, a Move instance is created in around 0.0005 seconds, but towards the end, this amount jumps up to a whopping 0.1 second / Move instance.

What could be the reason of this sudden time jump? I tried allowing more memory for this PHP script, but it doesn't help this situation.



from PHP - Repeated operations get slower and slower

No comments:

Post a Comment