Let’s start with creating a blank profile.
- In the menu, open View | Options.
- In the opened Options window, navigate to Subsystems | Profiles.
As you see, in addition to the Default profile, there are two other profiles called user1 and user2. These profiles also come with dotTrace by default.
- Add a new blank profile by clicking under the list of profiles. Let’s name it MyProfile.
Now, let’s apply this profile to the main thread and look at the results.
- To apply our profile, click the button and select the MyProfile profile.
As you see, regardless of the fact we didn’t include any subsystems in the profile, dotTrace shows us a number of predefined subsystems that cover all of the app’s calls:
- System code -- all calls that belong to standard system libraries and do not match the rules of user-defined subsystems.
- User code -- all calls that do not belong to standard system libraries and do not match the rules of user-defined subsystems.
- Special -- all calls that do not belong to .NET libraries.
Even on this stage, when no specific subsystems are added to the profile, we can approximately evaluate what subsystems affect performance more significantly. The clue to this is the so-called smart subsystems feature. As you see both in the subsystems bar and list, dotTrace Performance automatically splits each shown subsystem to a number of underlying subsystems. For example, the main contributor into the System code is the WaitMessage call (actually, this is just the time when our app does nothing and waits for the user input). System.Collections and System.Drawing subsystems (both probably related to our chart) also take a lot of time. To say for sure, let’s fill the blank profile with our own set of subsystems and proceed through the “finding bottlenecks” workflow.