Up to date
This page is up to date for Godot 4.1
.
If you still find outdated information, please open an issue.
General optimization tips¶
Introduction¶
In an ideal world, computers would run at infinite speed. The only limit to what we could achieve would be our imagination. However, in the real world, it's all too easy to produce software that will bring even the fastest computer to its knees.
Thus, designing games and other software is a compromise between what we would like to be possible, and what we can realistically achieve while maintaining good performance.
To achieve the best results, we have two approaches:
Work faster.
Work smarter.
And preferably, we will use a blend of the two.
Smoke and mirrors¶
Part of working smarter is recognizing that, in games, we can often get the player to believe they're in a world that is far more complex, interactive, and graphically exciting than it really is. A good programmer is a magician, and should strive to learn the tricks of the trade while trying to invent new ones.
The nature of slowness¶
To the outside observer, performance problems are often lumped together. But in reality, there are several different kinds of performance problems:
A slow process that occurs every frame, leading to a continuously low frame rate.
An intermittent process that causes "spikes" of slowness, leading to stalls.
A slow process that occurs outside of normal gameplay, for instance, when loading a level.
Each of these are annoying to the user, but in different ways.
Measuring performance¶
Probably the most important tool for optimization is the ability to measure performance - to identify where bottlenecks are, and to measure the success of our attempts to speed them up.
There are several methods of measuring performance, including:
Putting a start/stop timer around code of interest.
Using the Godot profiler.
Using external CPU profilers.
Using external GPU profilers/debuggers such as NVIDIA Nsight Graphics, Radeon GPU Profiler or Intel Graphics Performance Analyzers.
Checking the frame rate (with V-Sync disabled). Third-party utilities such as RivaTuner Statistics Server (Windows) or MangoHud (Linux) can also be useful here.
Using an unofficial debug menu add-on.
Be very aware that the relative performance of different areas can vary on different hardware. It's often a good idea to measure timings on more than one device. This is especially the case if you're targeting mobile devices.
Limitations¶
CPU profilers are often the go-to method for measuring performance. However, they don't always tell the whole story.
Bottlenecks are often on the GPU, "as a result" of instructions given by the CPU.
Spikes can occur in the operating system processes (outside of Godot) "as a result" of instructions used in Godot (for example, dynamic memory allocation).
You may not always be able to profile specific devices like a mobile phone due to the initial setup required.
You may have to solve performance problems that occur on hardware you don't have access to.
As a result of these limitations, you often need to use detective work to find out where bottlenecks are.
Detective work¶
Detective work is a crucial skill for developers (both in terms of performance, and also in terms of bug fixing). This can include hypothesis testing, and binary search.
Hypothesis testing¶
Say, for example, that you believe sprites are slowing down your game. You can test this hypothesis by:
Measuring the performance when you add more sprites, or take some away.
This may lead to a further hypothesis: does the size of the sprite determine the performance drop?
You can test this by keeping everything the same, but changing the sprite size, and measuring performance.
Binary search¶
If you know that frames are taking much longer than they should, but you're not sure where the bottleneck lies. You could begin by commenting out approximately half the routines that occur on a normal frame. Has the performance improved more or less than expected?
Once you know which of the two halves contains the bottleneck, you can repeat this process until you've pinned down the problematic area.
Profilers¶
Profilers allow you to time your program while running it. Profilers then provide results telling you what percentage of time was spent in different functions and areas, and how often functions were called.
This can be very useful both to identify bottlenecks and to measure the results of your improvements. Sometimes, attempts to improve performance can backfire and lead to slower performance. Always use profiling and timing to guide your efforts.