Phaser.Struct.Set Performance

When profiling, I am seeing over 30% of time spent in the contains() method of Phaser.Structs.Set:

contains: function (value)
{
return (this.entries.indexOf(value) > -1);
},

The call to Phaser.Structs.Set.contains() is a result of collideSpriteVsGroup(), where the game update loop checks to see if bullets are hiting the player.

Has anyone seen this behavior before? My immediate thought is to optimize the Set class so the entries are indexed. I batch insert into a group at the start of the game, so I would be willing so invest a little time in the create section in order to speed up the update loop.

I think that’s possible if there are very frequent collisions. Does it look like there are very frequent collisions?

I have a large reservoir (200) for bullet objects. Most of the time the vast majority are not active, so there is no performance hit for the objects themselves. However, the contain() method seems to iterate through the entire set when doing collision checks, regardless of whether the objects are active or not.

For now I have reduced the object pool to 100, which gave an immense performance boost.

I think that’s right, but collideSpriteVsGroup() calls group.contains() only on the results of the collision search. If there are no collisions, it shouldn’t be called at all.

Do the inactive bullets have body.enable === false?

I experimented a bit more. The specific problem was player bullets checking for collision with enemies, and the behavior occurred even when all player bullets in the pool were disabled. Changing body.enable = false for all objects did not change anything. Tracing backwards through the code, collideGroupVsGroup() is called:

    collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly)
{
    if (group1.length === 0 || group2.length === 0)
    {
        return;
    }

    var children = group1.getChildren();

    for (var i = 0; i < children.length; i++)
    {
        this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly);
    }
},

The important line there is: group1.getChildren();
The PhysicsGroup inherits getChildren() from Group, and Group simply returns the array entries. I cannot find any point in the flow where either GameObject active is checked, or the body.enabled is checked. Given group1 has n1 objects, and group2 has n2 objects, this looks like an n1x(n2/2) loop on every update step. (I do see what looks like quad tree code in there, so n2/2 may not be exact, but the time sink is actually in the native contains() method of Javascript, which is a linear search on basic arrays.)

It looks like a check for the physics body should be somewhere in that chain, but if it is there, I didn’t find it.

collideSpriteVsGroup() seems to be missing a check for body.enable within group2. It does check in the sprite argument, though, so you might get a small benefit by making the bullets group the first argument to the collider (if it’s not).