Unity Profiler

Checked with version: 2018.1

-

Difficulty: Advanced

The Unity Profiler is an instrumentation profiler. The Profiler provides per-frame performance metrics, which helps identify bottlenecks. It also gives you an idea of what performance is like when running an application outside of the Editor. Bear in mind that the Profiler has an overhead. The most precise way to review performance is to create a build for the target platform and profile it on the target device. While the best performance observable would be running in a non-development build, the Unity Profiler only allows for use with development builds.

To enable profiling for an app, go to Build Settings (menu: File > Build Settings), and select Development Build and Autoconnect Profiler. When launching the application, the Profiler automatically connects. Or, attach it to the application in the Profiler Controls via the Editor drop-down menu.

The Profiler helps you understand how much time the application spends rendering each frame, and splits this into CPU, rendering, memory, audio, physics, UI, and network. To learn more about the Profiler, see Introduction to the Profiler video and the documentation.

Note: Don’t compare the Unity Profiler results across Unity versions. The overhead of the Unity Profiler itself is not insignificant, and changes to the internal Profiler architecture across releases might significantly affect the results.

Underreporting

On rare occasions, the Profiler does not display Unity internal systems with sufficient profile labels.

Should you encounter such a missing label (or require more detailed information about a given subsystem), please file a bug report and let us know about the missing marker.

Editor profiling

There are significant caveats to consider when profiling a Project in the Editor. Sometimes lag and jitter may occur as the host renders the same content multiple times, depending on how many views are open. Rendering the Editor itself also has some overhead. It is vital to profile performance regularly on the target device and not rely solely on data obtained when profiling in the Editor.

Deep profiling

Use Unity’s Deep Profile mode to locate the specific causes of managed allocations. In Deep Profile mode, all method calls are recorded individually, providing a clearer view of where managed allocations occur within the method call tree.

Note: Since Unity 2017.3, Deep Profile mode works not only in the Editor but also on Android and Desktop using the Mono scripting backend.

To enable Deep Profile mode on Desktop, use the -deepprofiling command line argument.

To enable Deep Profile mode on Android, use the adb command line argument. For example:

~$ adb shell am start -n com.company.game/com.unity3d.player.UnityPlayerActivity -e 'unity' '-deepprofiling'

The Deep Profiler button remains grayed out during profiling.

Profiling Memory in Editor

Profiling memory in the Editor is useful for understanding the general trends behind memory behavior, but not for comparing actual values on a specific target device.

  • Every Mesh has the read/write flag turned on during a run in the Editor, irrespective of the Read/Write Enabled setting in the Asset Import Settings. This alone doubles the Mesh memory reflected in the Profiler.

  • Profiling in the Editor also deactivates vertex compression.

  • Running the application in the Editor produces more temporary memory allocations. For example, GetComponent uses temporary GC allocations in the Editor when the Component is null. That way, Unity can throw an exception in the Editor which does not occur at run time on the target platform.

Rendering Statistics

Unity provides the option to display real-time rendering statistics in the Game view, such as FPS, draw calls, VRAM usage, triangles and vertex counts. To display a Statistics overlay with real-time rendering information, go to the Game view and click the Stats button in the toolbar above the viewport. These statistics help you analyze and improve batching and GPU cost by indicating how many draw calls Unity issues and how many draw calls you save with batching.

The Statistics window is only available in the Game view.

For more detailed rendering statistics, open the rendering tab of the Profiler.

The rendering tab shows more details per frame.

In the above example, the empty Scene has 5 SetPass calls and issues 5 draw calls.

  • SetPass call count is crucial because it negatively impacts performance the higher it is. SetPass calls perform pipeline state changes under the hood. SetPass call count should be as low as possible.

  • Draw calls per-se are not necessarily problematic as long as the application is not CPU bound. This is because draw calls are executed on the render thread which runs on the CPU. Reduce the probability of being CPU bound by using multithreaded rendering.

Issuing Draw Calls

For better performance, issue more draw calls with the same pipeline state than fewer draw calls with more changed states. Having many draw calls without a state change lets Unity write the draw commands to the command buffer directly, which is the fastest driver path. The fastest driver path enables Unity to put the indices for all collected draw calls into one buffer. Otherwise, Unity needs to split the data up into several buffers due to the state changes, which results in more store and load calls on the graphics memory due to multiple buffers.

Multithreaded Rendering & Graphics Jobs

Multithreaded rendering and graphics jobs often help to improve performance, but when debugging or profiling they can hinder you from seeing all relevant numbers. To identify issues easier, disable the setting when profiling graphics-specific. For detailed information, see the Optimizing Graphics in Unity guide.

Unity Frame Debugger

The Frame Debugger allows you to freeze playback on a single frame and step through individual events. This enables you to see how Unity constructs a Scene and identify optimization opportunities. It also shows GameObjects that render unnecessarily, and you can disable those GameObjects to reduce draw calls per-frame.

Note: The Frame Debugger does not show individual draw calls or state changes. Instead, it shows how Unity constructs a frame. The Frame Debugger also does not provide enough information about the draw call itself, such as matrices or vertex screen coordinates -- especially so on legacy Shaders (for example, Unlit/Texture). Only native GPU profilers show detailed draw call information, usually with timing information attached. The Frame Debugger can be very helpful in debugging pipeline problems or issues with batching, primarily when working with Unity UI. For more information, read the Unity Frame Debugger documentation.

Overdraw View

Unity provides a specific render mode for viewing overdraw in a Scene. Please read more about overdraw and the overdraw view in the Optimizing Graphics in Unity guide.

Memory Profiler

This section describes a demo Project that demonstrates the use of the profiler API. The Project itself is available on Bitbucket, and more information is available in the Memory profiling documentation.

A snapshot of the Memory Profiler available on Bitbucket.

The tool tracks memory allocated by Unity's subsystems, and from user scripts only when using the IL2CPP back-end before Unity 2017.3. The Memory Profiler cannot track allocations from third-party tools using a custom allocator. As of 2017.3, the tool also supports tracking managed objects under the Mono scripting runtime.