Performance Statistics#

../../_images/performance_statistics1.png

Arcade includes performance monitoring tools to help you optimize your game. This example demonstrates the following performance api features:

If you do not want to display graphs in your game window, you can use arcade.print_timings() to print out the count and average time for all dispatched events with the function. The output looks like this:

Event          Count Average Time
-------------- ----- ------------
on_activate        1       0.0000
on_resize          1       0.0000
on_show            1       0.0000
on_update         59       0.0000
on_expose          1       0.0000
on_draw           59       0.0021
on_mouse_enter     1       0.0000
on_mouse_motion  100       0.0000

See Performance Information for more information about the performance api.

performance_statistics.py#
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
"""
Performance Statistic Display Example

This example demonstrates how to use a few performance profiling tools
built into arcade:

* arcade.enable_timings
* arcade.PerfGraph
* arcade.get_fps
* arcade.print_timings
* arcade.clear_timings

A large number of sprites bounce around the screen to produce load. You
can adjust the number of sprites by changing the COIN_COUNT constant.

Artwork from https://kenney.nl

If Python and Arcade are installed, this example can be run from the
command line with:
python -m arcade.examples.performance_statistics
"""
import random
import arcade

# --- Constants ---
SPRITE_SCALING_COIN = 0.25
SPRITE_NATIVE_SIZE = 128
SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING_COIN)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Performance Statistics Display Example"

# Size of performance graphs and distance between them
GRAPH_WIDTH = 200
GRAPH_HEIGHT = 120
GRAPH_MARGIN = 5

COIN_COUNT = 1500


# Turn on tracking for the number of event handler
# calls and the average execution time of each type.
arcade.enable_timings()


class Coin(arcade.Sprite):
    """ Our coin sprite class """
    def update(self):
        """ Update the sprite. """
        # Setting the position is faster than setting x & y individually
        self.position = (
            self.position[0] + self.change_x,
            self.position[1] + self.change_y
        )

        # Bounce the coin on the edge of the window
        if self.position[0] < 0:
            self.change_x *= -1
        elif self.position[0] > SCREEN_WIDTH:
            self.change_x *= -1
        if self.position[1] < 0:
            self.change_y *= -1
        elif self.position[1] > SCREEN_HEIGHT:
            self.change_y *= -1


class MyGame(arcade.Window):
    """ Our custom Window Class"""

    def __init__(self):
        """ Initializer """
        # Call the parent class initializer
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)

        # Variables to hold game objects and performance info
        self.coin_list: arcade.SpriteList = None
        self.perf_graph_list: arcade.SpriteList = None
        self.fps_text: arcade.Text = None
        self.frame_count: int = 0  # for tracking the reset interval

        arcade.set_background_color(arcade.color.AMAZON)

    def add_coins(self, amount):

        # Create the coins
        for i in range(amount):
            # Create the coin instance
            # Coin image from kenney.nl
            coin = Coin(":resources:images/items/coinGold.png", SPRITE_SCALING_COIN)

            # Position the coin
            coin.position = (
                random.randrange(SPRITE_SIZE, SCREEN_WIDTH - SPRITE_SIZE),
                random.randrange(SPRITE_SIZE, SCREEN_HEIGHT - SPRITE_SIZE)
            )

            coin.change_x = random.randrange(-3, 4)
            coin.change_y = random.randrange(-3, 4)

            # Add the coin to the lists
            self.coin_list.append(coin)

    def setup(self):
        """ Set up the game and initialize the variables. """

        # Sprite lists
        self.coin_list = arcade.SpriteList(use_spatial_hash=False)

        # Create some coins
        self.add_coins(COIN_COUNT)

        # Create a sprite list to put the performance graphs into
        self.perf_graph_list = arcade.SpriteList()

        # Calculate position helpers for the row of 3 performance graphs
        row_y = self.height - GRAPH_HEIGHT / 2
        starting_x = GRAPH_WIDTH / 2
        step_x = GRAPH_WIDTH + GRAPH_MARGIN

        # Create the FPS performance graph
        graph = arcade.PerfGraph(GRAPH_WIDTH, GRAPH_HEIGHT, graph_data="FPS")
        graph.position = starting_x, row_y
        self.perf_graph_list.append(graph)

        # Create the on_update graph
        graph = arcade.PerfGraph(GRAPH_WIDTH, GRAPH_HEIGHT, graph_data="on_update")
        graph.position = starting_x + step_x, row_y
        self.perf_graph_list.append(graph)

        # Create the on_draw graph
        graph = arcade.PerfGraph(GRAPH_WIDTH, GRAPH_HEIGHT, graph_data="on_draw")
        graph.position = starting_x + step_x * 2, row_y
        self.perf_graph_list.append(graph)

        # Create a Text object to show the current FPS
        self.fps_text = arcade.Text(
            f"FPS: {arcade.get_fps(60):5.1f}",
            10, 10, arcade.color.BLACK, 22
        )

    def on_draw(self):
        """ Draw everything """

        # Clear the screen
        self.clear()

        # Draw all the coin sprites
        self.coin_list.draw()

        # Draw the graphs
        self.perf_graph_list.draw()

        # Get & draw the FPS for the last 60 frames
        self.fps_text.value = f"FPS: {arcade.get_fps(60):5.1f}"
        self.fps_text.draw()

    def on_update(self, delta_time):
        """ Update method """
        self.frame_count += 1

        # Print and clear timings every 60 frames
        if self.frame_count % 60 == 0:
            arcade.print_timings()
            arcade.clear_timings()

        # Move the coins
        self.coin_list.update()


def main():
    """ Main function """
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()