Measuring Performance with the Built-in Profiler
Unity iOS provides your project with a built-in performance profiler. Note that it is disabled by default. In order to enable it you will have to open the Unity -generated XCode project, select the AppController.mm
file and change #define ENABLE_INTERNAL_PROFILER 0
to #define ENABLE_INTERNAL_PROFILER 1
. Choose in the XCode menu to display output (GDB) console and then run your project. Unity iOS will output statistics to the console window every 30 frames. For example:
iPhone/iPad Unity internal profiler stats: cpu-player> min: 9.8 max: 24.0 avg: 16.3 cpu-ogles-drv> min: 1.8 max: 8.2 avg: 4.3 cpu-waits-gpu> min: 0.8 max: 1.2 avg: 0.9 cpu-present> min: 1.2 max: 3.9 avg: 1.6 frametime> min: 31.9 max: 37.8 avg: 34.1 draw-call #> min: 4 max: 9 avg: 6 | batched: 10 tris #> min: 3590 max: 4561 avg: 3871 | batched: 3572 verts #> min: 1940 max: 2487 avg: 2104 | batched: 1900 player-detail> physx: 1.2 animation: 1.2 culling: 0.5 skinning: 0.0 batching: 0.2 render: 12.0 fixed-update-count: 1 .. 2 mono-scripts> update: 0.5 fixedUpdate: 0.0 coroutines: 0.0 mono-memory> used heap: 233472 allocated heap: 548864 max number of collections: 1 collection total duration: 5.7
All times are measured in milliseconds per frame. You can see the minimum, maximum and average times over last 30 frames.
General CPU Activity
cpu-player | Displays time your game spends inside Unity engine and executing scripts on the CPU. |
cpu-ogles-drv | Displays time spent in the OpenGL ES driver on the CPU. Many factors like number of draw calls, amount of internal rendering state changes, rendering pipeline setup and even number of processed vertices can have effect on the driver time. |
cpu-waits-gpu | Displays time CPU spent waiting until GPU finishes rendering. If this number exceeds 2-3 milliseconds, your application is most probably fillrate/GPU processing bound. |
cpu-present | The amount of time spent executing the presentRenderbuffer command in OpenGL ES. |
frametime | Represents overall time of a game frame. Note that iPhone/iPad hardware is always locked at 60Hz refresh rate, thus you will always get multiples times of ~16.7ms (1000ms/60Hz = ~16.7ms). |
Rendering Statistics
draw-call # | The number of draw calls per frame. Keep it as low as possible. |
tris # | Total number of triangles sent for rendering. |
verts # | Total number of vertices sent for rendering. You should keep this number below 10000, if you use only static geometry. On the other hand, if you have lots of skinned geometry, then you should keep this number much lower. |
batched | Number of draw-calls, triangles and vertices which were automatically batched by the engine. Comparing these numbers with draw-call and triangle totals will give you an idea how well is your scene prepared for batching. Share as many materials among your objects to improve batching. |
Detailed Unity Player Statistics
player-detail section provides a detailed breakdown of what is happening inside the engine:
physx | Time spent on physics. |
animation | Time spent animating bones. |
culling | Time spent culling objects outside camera frustum. |
skinning | Time spent applying animations to skinned meshes. |
batching | Time spent batching geometry. Batching dynamic geometry is considerably more expensive than batching static geometry. |
render | Time spent rendering visible objects. |
fixed-update-count | Minimum and maximum number of FixedUpdates executed during this frame. Too many FixedUpdate will deteriorate perforamance really fast. Follow some simple guidelines to setup an effective fixed delta time. |
Detailed Scripts Statistics
mono-scripts section provides a detailed breakdown of time spent in Mono runtime:
update | Total time spent executing all Update() functions in scripts. |
fixedUpdate | Total time spent executing all FixedUpdate() functions in scripts. |
coroutines | Time spent inside script coroutines. |
Detailed Statistics on Memory Allocated by Scripts
mono-memory section gives you an idea how much memory is used by the Mono garbage collector:
allocated heap | Total amount of memory which can be filled with objects. If there is a need for more objects than the size of allocated heap, then Garbage Collector will start a collection phase during which all unreferenced objects will be thrown away from memory. If there is not enough free memory after the collection phase, then the allocated heap will grow in size. |
used heap | Portion of the allocated heap which is currently used up by objects. Every time you create a new class instance (not a struct) this number will grow until collection phase is invoked. |
max number of collections | Number of garbage collection passes during the last 30 frames. |
collection total duration | Total time (in milliseconds) of all garbage collection passes that happened during the last 30 frames. |