Timing Drawing Speed
Welcome to Speed Testing
In this lab, you will measure how long drawing functions take to run. This is a real skill that game programmers use every day. Let's build something amazing!
If you are writing a video game, you want the screen to update as fast as possible. A slow drawing function makes the game look choppy. A fast one makes it look smooth.
In this lab, you will measure two different ways to draw a circle and compare their speeds.
Why Speed Matters
Every time you draw a shape on the display, the Pico must do math calculations. For a circle, it needs to figure out which pixels to turn on.
Different algorithms (step-by-step methods) can solve the same problem in different amounts of time. You want to find the fastest one.
Measuring Time in MicroPython
MicroPython has a function called ticks_us() that returns the current time in microseconds (one millionth of a second). You call it before and after your drawing function. Then you subtract to find how long it took.
1 2 3 4 5 6 7 | |
What each line does:
from utime import ticks_us— loads the microsecond timer.start = ticks_us()— saves the current time before the function.my_function()— runs whatever you want to measure.end = ticks_us()— saves the time after the function finishes.end - start— the difference is how many microseconds the function took.
MicroPython also has ticks_cpu() for even finer measurements. On the Raspberry Pi Pico, ticks_cpu() gives the same result as ticks_us().
Key Idea
A microsecond is one millionth of a second. The Pico can do millions of operations per second. Small differences in draw time add up fast when you are animating many frames.
Comparing Two Circle Drawing Algorithms
There are two common ways to draw a circle:
- Row Scanner Method — scans every pixel in a square around the circle. For each pixel, it calculates how far that pixel is from the center. If the distance is within the circle's edge thickness, it turns the pixel on.
- Point Draw Method — steps around the circle degree by degree (0, 2, 4, … 360). For each angle, it calculates one point on the edge of the circle using sine and cosine math, then turns that pixel on.
For small circles, the Point Draw Method is slow — it still tries 180 points even for a tiny circle. The Row Scanner only checks the pixels it needs to. But for large circles, the Row Scanner must check thousands of pixels, while the Point Draw still only needs 180 points.
Here is a program that times both methods and prints the results:
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 | |
What each section does:
fast_circle()— the Point Draw method. It steps around the circle 2 degrees at a time.math.cos()andmath.sin()find each point on the edge.circle()— the Row Scanner method. It checks every pixel in the bounding square and calculates the exact distance from the center.ticks_us()before and after each call — measures how long each method takes.print(...)— shows the timing result in the Thonny console.
Monty's Tip
Run the timing test with different circle sizes! Try radii of 5, 10, 20, and 30. See if the Row Scanner or the Point Draw method wins at each size.
Watch Out!
The Point Draw method can leave gaps in very small circles. If you see a broken ring, try stepping by 1 degree instead of 2 in the range(0, 360, 2) line — but that will be slower.
Challenge Tasks
Try these experiments to go further:
- Write a program that compares drawing speed for circles of different sizes (radius 5, 10, 20, and 30).
- Change the
fast_circle()function to skip every 3rd point instead of every 2nd. Does it look broken for small circles? - Can you write a function that automatically chooses the faster algorithm based on the circle size?
- Can you add a parameter that controls how many points are skipped in the Point Draw method?
Great Work!
You measured real drawing performance on your microcontroller! Next, you will use what you know to animate a bouncing ball on the screen.