ProfilerMarker API guide | Unity Profiling Core API | 0.1.0-preview.1
docs.unity3d.com
    Show / Hide Table of Contents

    ProfilerMarker API guide

    Use ProfilerMarker to mark up resource-intensive script code blocks and make them visible in the Unity Profiler.

    This can be useful because by default, the built-in Unity Profiler does not profile all method calls. Also, if you enable Deep Profiling, it causes a large overhead that significantly slows down your application execution and skews the results.

    To use the ProfilerMarker API, start your code with ProfilerMarker.Begin() and end it with ProfilerMarker.End() like the following:

    using UnityEngine;
    using Unity.Profiling;
    
    public class ProfilerMarkerExample
    {
        static readonly ProfilerMarker k_MyCodeMarker = new ProfilerMarker("My Code");
    
        void Update() {
            k_MyCodeMarker.Begin();
            Debug.Log("This code is being profiled");
            k_MyCodeMarker.End();
        }
    }
    

    Unity then records and reports that code block's execution time to the Profiler, and displays it in the CPU Profiler module without the need to use Deep Profiling. It displays it as a new entry in the Hierarchy View of the CPU Profiler module, as follows:

    Profiler sample in Profiler Window.
    Profiler sample in Profiler Window.

    You can also capture this information with the Recorder profiling API. During development in the Editor and in Development Players, you can use it to get a performance overview of the different parts of your code and to identify performance issues.

    You can add as many Profiler samples as you like: these calls have zero overhead when Unity deploys them in a non-development build. Begin and End methods are marked with ConditionalAttribute. Unity conditionally compiles them away, and as such, they have zero execution overhead in non-developmenet (Release) builds. The marker field will be present in release build though, taking up memory for it's IntPtr, i.e. 8 Byte.

    ProfilerMarker represents a named Profiler handle and is the most efficient way of profiling your code. You can use it in any C# code of your application.

    Using ProfilerMarker

    You can also use ProfilerMarker.Auto() in your code to ensure that ProfilerMarker.End() is automatically called at the end of the code block. The following calls are equivalent:

    using Unity.Profiling;
    
    public class MySystemClass
    {
        static readonly ProfilerMarker k_UpdatePerfMarker = new ProfilerMarker("MySystem.Update");
    
        public void Update()
        {
            k_UpdatePerfMarker.Begin();
            // ...
            k_UpdatePerfMarker.End();
    
            using (k_UpdatePerfMarker.Auto())
            {
                // ...
            }
        }
    }
    

    ProfilerMarker.Auto() can not be compiled out in non-development (Release) builds but just returns null and thus adding minimal overhead.

    Using ProfilerMarker with integer of floating point parameters

    Sometimes you might want to provide additional context to your code samples, to identify specific conditions on why the code might have been running for a long time. For example, if your system is carrying out simulations of a number of objects, you can pass the number of objects with a Profiler sample. If you then see an abnormal number along with a long sample duration, that might mean you have to use another thread for simulation or split the CPU work across multiple frames (timeslicing) or even do a game design adjustments to prevent frame drops.

    using Unity.Profiling;
    
    public class MySystemClass
    {
        static readonly ProfilerMarker<int> k_PreparePerfMarker = new ProfilerMarker<int>("MySystem.Prepare", "Objects Count");
        static readonly ProfilerMarker<float> k_SimulatePerfMarker = new ProfilerMarker<float>(ProfilerCategory.Scripts, "MySystem.Simulate", "Objects Density");
    
        public void Update(int objectsCount)
        {
            k_PreparePerfMarker.Begin(objectsCount);
            // ...
            k_PreparePerfMarker.End();
    
            using (k_SimulatePerfMarker.Auto(objectsCount * 1.0f))
            {
                // ...
            }
        }
    }
    

    Note: The ProfilerMarker supports up to three numeric parameters: ProfilerMarker<TP1>, ProfilerMarker<TP1, TP2> and ProfilerMarker<TP1, TP2, TP3>.

    Using ProfilerMarker with a string parameter

    Similarly, when you load level or data files you might want to see the name of the level or file which took longer than expected to process. Use ProfilerMarkerExtension methods to pass a string parameter along with a Profiler sample:

    using Unity.Profiling;
    
    public class MySystemClass
    {
        static readonly ProfilerMarker k_PreparePerfMarker = new ProfilerMarker("MySystem.Prepare");
    
        public void Prepare(string path)
        {
            k_PreparePerfMarker.Begin(path);
            // ...
            k_PreparePerfMarker.End();
        }
    }
    

    Where to see the parameters

    The samples that ProfilerMarker.Begin()/End() or ProfilerMarker.Auto generates are visible in Timeline View and Hierarchy View of the CPU module in the Profiler Window.

    Profiler sample with metadata in Timeline View.
    Profiler sample with metadata in Timeline View.

    Profiler sample with metadata in Hierarchy View.
    Profiler sample with metadata in Hierarchy View.

    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023