Skip to content

Typical bottlenecks

FW edited this page Jun 9, 2019 · 5 revisions

Typical bottlenecks

Multiple filters

SLOW:

self.units(ZERGLING).filter(lambda unit: unit.health_percentage > 0.5)

    .closer_than(3, self.start_location).noqueue

This creates four new Units objects every time you call it.

FAST:

self.units.filter(lambda unit: unit.type_id==ZERGLING and unit.noqueue

    and unit.health_percentage > 0.5 and unit.distance_to(self.start_location) < 3)

This only creates one new Units object. You can improve it even more by ordering it so that the other units get filtered out as early as possible.


Loops

SLOW:

for marine in marines:
   enemies = self.known_enemy_units.filter(lambda unit: unit.can_attack_ground)
   marine.run_away_from(enemies.closest_to(marine))

This creates enemies and filter to calculate it for every marine, although it will always return the same result.

FAST:

enemies = self.known_enemy_units.filter(lambda unit: unit.can_attack_ground)
for marine in marines:   
   marine.run_away_from(enemies.closest_to(marine))

This only calculates enemies only one time.


Skipping functions

SLOW:

# in on_step
self.build_depots()
self.build_barracks()
self.expand()

This will call the three functions in every frame, even if they cant build anything.

FAST:

# in on_step
if self.minerals >= 100:
    self.build_depots()
    if self.minerals >= 150:
        self.build_barracks()
        if self.minerals >= 400:
            self.expand()

This will skip the functions that can not build anything anyways because the resources are not sufficient.

You can also do these checks inside the building functions to keep the code cleaner.

Clone this wiki locally