You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Measure and analyze CPU performance issues in your C#, Visual Basic, C++, or F# application by using the debugger-integrated diagnostics tools in Visual Studio.
4
-
ms.date: 02/05/2025
4
+
ms.date: 04/23/2026
5
5
ms.topic: tutorial
6
6
helpviewer_keywords:
7
7
- "Profiling Tools, quick start"
@@ -42,7 +42,11 @@ In this tutorial, you will:
42
42
43
43
4. You can choose whether to see **CPU Usage**, [Memory Usage](../profiling/Memory-Usage.md), or both, with the **Select Tools** setting on the toolbar. If you are running Visual Studio Enterprise, you can also enable or disable IntelliTrace in **Tools** > **Options** > **IntelliTrace**.
44
44
45
-
::: moniker range=">=vs-2022"
45
+
::: moniker range="visualstudio"
46
+

47
+
::: moniker-end
48
+
49
+
::: moniker range="vs-2022"
46
50

47
51
::: moniker-end
48
52
@@ -52,7 +56,12 @@ In this tutorial, you will:
52
56
5. Click **Debug** > **Start Debugging** (or **Start** on the toolbar, or **F5**).
53
57
54
58
When the app finishes loading, the Summary view of the Diagnostics Tools appears. If you need to open the window, click **Debug** > **Windows** > **Show Diagnostic Tools**.
55
-
::: moniker range=">=vs-2022"
59
+
60
+
::: moniker range="visualstudio"
61
+

62
+
::: moniker-end
63
+
64
+
::: moniker range="vs-2022"
56
65

57
66
::: moniker-end
58
67
@@ -63,27 +72,40 @@ In this tutorial, you will:
63
72
64
73
7. While the debugger is paused, enable the collection of the CPU Usage data and then open the **CPU Usage** tab.
65
74
66
-
::: moniker range=">=vs-2022"
67
-

68
-
::: moniker-end
75
+
::: moniker range="visualstudio"
76
+

69
77
78
+
When you select **Start Recording**, Visual Studio will begin recording your functions and how much time they take to execute. You can only view this collected data when your application is halted at a breakpoint.
79
+
::: moniker-end
70
80
81
+
::: moniker range="vs-2022"
82
+

83
+
71
84
When you choose **Record CPU Profile**, Visual Studio will begin recording your functions and how much time they take to execute. You can only view this collected data when your application is halted at a breakpoint.
85
+
::: moniker-end
72
86
73
87
8. Hit F5 to run the app to your second breakpoint.
74
88
75
89
Now, you now have performance data for your application specifically for the region of code that runs between the two breakpoints.
76
90
77
91
The profiler begins preparing thread data. Wait for it to finish.
78
92
79
-
::: moniker range=">=vs-2022"
93
+
::: moniker range="visualstudio"
94
+

95
+
::: moniker-end
96
+
97
+
::: moniker range="vs-2022"
80
98

81
99
::: moniker-end
82
100
83
101
84
102
The CPU Usage tool displays the report in the **CPU Usage** tab.
85
103
86
-
::: moniker range=">=vs-2022"
104
+
::: moniker range="visualstudio"
105
+

106
+
::: moniker-end
107
+
108
+
::: moniker range="vs-2022"
87
109

88
110
::: moniker-end
89
111
@@ -104,29 +126,84 @@ In this tutorial, you will:
104
126
105
127
We recommend that you begin analyzing your data by examining the list of functions under CPU Usage, identifying the functions that are doing the most work, and then taking a closer look at each one.
106
128
107
-
1. In the function list, examine the functions that are doing the most work.
129
+
:::moniker range="visualstudio"
130
+
1. In the **Top Functions** list, examine the functions that are doing the most work.
131
+
132
+

108
133
109
-
::: moniker range=">=vs-2022"
110
-

111
-
::: moniker-end
134
+
2. In the **Top Functions** list, select one of your app functions that's doing a lot of work.
135
+
136
+
When you select a function, the **Functions** view opens in the left pane. Select **Caller/Callee** view from the drop-down menu.
137
+
138
+
> [!TIP]
139
+
> Functions in the left pane are listed in order starting with those doing the most work (they're not in call order). This helps you quickly identify the longest running functions.
112
140
141
+
:::image type="content" source="../profiling/media/visualstudio/diagnostic-tools-caller-callee.png" alt-text="Screenshot that shows the Diagnostics Tools Caller/Callee view." lightbox="../profiling/media/visualstudio/diagnostic-tools-caller-callee.png":::
142
+
143
+
In this view, the selected function shows up in the heading and in the **Current Function** box (DoWork, in this example). The function that called the current function is shown on the left under **Calling Functions**, and any functions called by the current function are shown in **Called Functions** box on the right. (You can select either box to change the current function.)
144
+
145
+
This view shows you the total time (ms) and the percentage of the overall app running time that the function has taken to complete. **Function Body** also shows you the total amount of time (and the percentage of time) spent in the function body excluding time spent in calling and called functions.
146
+
147
+
> [!TIP]
148
+
> High values in **Function Body** may indicate a performance bottleneck within the function itself.
149
+
150
+
3. To see a higher-level view showing the order in which the functions are called, select **Call Tree** from the drop-down list at the top of the pane.
151
+
152
+
Each numbered area in the figure relates to a step in the procedure.
153
+
154
+

155
+
156
+
|Image|Description|
157
+
|-|-|
158
+
||The top-level node in CPU Usage call tree, representing the application.|
159
+
||In most apps, when the [Show External Code](#view-external-code) option is disabled, the second-level node is an **[External Call]** node that contains the system and framework code that starts and stops the app, draws the UI, controls thread scheduling, and provides other low-level services to the app.|
160
+
||The children of the second-level node are the user-code methods and asynchronous routines that are called or created by the second-level system and framework code.|
161
+
||Child nodes of a method contain data only for the calls of the parent method. When **Show External Code** is disabled, app methods can also contain an **[External Call]** node.|
162
+
163
+
Here is more information on the column values:
164
+
165
+
-**Total CPU** indicates how much work was done by the function and any functions called by it. High total CPU values point to the functions that are most expensive overall.
166
+
167
+
-**Self CPU** indicates how much work was done by the code in the function body, excluding the work done by functions that were called by it. High **Self CPU** values may indicate a performance bottleneck within the function itself.
168
+
169
+
-**Modules** The name of the module containing the function, or the number of modules containing the functions in an [External Call] node.
170
+
171
+
To see the function calls that use the highest percentage of the CPU in the call tree view, click **Expand Hot Path**. The hot path can help focus your investigation on the area that would have the most impact.
172
+
173
+
174
+

175
+
176
+
> [!NOTE]
177
+
> If you see code in the call tree marked as "broken" code or "unwalkable stack", this indicates that Event Tracing for Windows (ETW) events were likely dropped. Try collecting the same trace a second time to resolve the issue.
178
+
179
+
4. To see a different view of the data, select **Flame Graph** from the drop-down list at the top of the pane.
180
+
181
+
The flame graph provides a different visualization of the call tree that may help you to analyze the data. For more information, see [Identify hot paths with a flame graph](../profiling/flame-graph.md).
182
+
183
+
5. To see views of the data aggregated by function or by module, select **Functions** or **Modules** from the drop-down list at the top of the pane.
184
+
185
+
These views help to identify functions or modules that might be performance bottlenecks due to a combination of high call counts and/or performance issues.
186
+
187
+

188
+
::: moniker-end
189
+
190
+
:::moniker range="vs-2022"
191
+
1. In the function list, examine the functions that are doing the most work.
192
+
193
+

113
194
114
195
> [!TIP]
115
196
> Functions are listed in order starting with those doing the most work (they're not in call order). This helps you quickly identify the longest running functions.
116
197
117
198
2. In the function list, double-click one of your app functions that is doing a lot of work.
118
199
119
-
::: moniker range=">=vs-2022"
120
-
121
200
When you double-click a function, the **Functions** view opens in the left pane. Select **Caller/Callee** view from the drop-down menu.
122
201
123
202

124
203
125
204
In this view, the selected function shows up in the heading and in the **Current Function** box (DoWork, in this example). The function that called the current function is shown on the left under **Calling Functions**, and any functions called by the current function are shown in **Called Functions** box on the right. (You can select either box to change the current function.)
126
205
127
206
This view shows you the total time (ms) and the percentage of the overall app running time that the function has taken to complete. **Function Body** also shows you the total amount of time (and the percentage of time) spent in the function body excluding time spent in calling and called functions.
128
-
::: moniker-end
129
-
130
207
131
208
> [!TIP]
132
209
> High values in **Function Body** may indicate a performance bottleneck within the function itself.
@@ -160,7 +237,6 @@ We recommend that you begin analyzing your data by examining the list of functio
160
237
> [!NOTE]
161
238
> If you see code in the call tree marked as "broken" code or "unwalkable stack", this indicates that Event Tracing for Windows (ETW) events were likely dropped. Try collecting the same trace a second time to resolve the issue.
162
239
163
-
::: moniker range=">=vs-2022"
164
240
4. To see a different view of the data, select **Flame Graph** from the drop-down list at the top of the pane.
165
241
166
242
The flame graph provides a different visualization of the call tree that may help you to analyze the data. For more information, see [Identify hot paths with a flame graph](../profiling/flame-graph.md).
@@ -174,9 +250,19 @@ We recommend that you begin analyzing your data by examining the list of functio
174
250
175
251
## View external code
176
252
177
-
::: moniker range=">=vs-2022"
253
+
::: moniker range="visualstudio"
254
+
255
+
External code is functions in system and framework components that are executed by the code you write. External code includes functions that start and stop the app, draw the UI, control threading, and provide other low-level services to the app. In most cases, you won't be interested in external code, and so the CPU Usage tool gathers the external functions of a user method into one **[External Call]** node.
256
+
257
+
If you want to view the call paths of external code, deselect **Show Just My Code** from the **Settings** list in the main **Diagnostic Tools** window and then select **Apply**.
258
+
259
+

260
+
261
+
::: moniker-end
262
+
263
+
::: moniker range="vs-2022"
178
264
179
-
External code are functions in system and framework components that are executed by the code you write. External code includes functions that start and stop the app, draw the UI, control threading, and provide other low-level services to the app. In most cases, you won't be interested in external code, and so the CPU Usage tool gathers the external functions of a user method into one **[External Call]** node.
265
+
External code is functions in system and framework components that are executed by the code you write. External code includes functions that start and stop the app, draw the UI, control threading, and provide other low-level services to the app. In most cases, you won't be interested in external code, and so the CPU Usage tool gathers the external functions of a user method into one **[External Call]** node.
180
266
181
267
If you want to view the call paths of external code, deselect **Show Just My Code** from the **Settings** list and then choose **Apply**.
0 commit comments