Profiling WPF Applications from the Command Line


Toward the end of my next-to-last post I suggested using the command-line to control profiling.  I’ve been experimenting with this functionality and wanted to post what I’ve learned. 


First, IanWho’s blog is a pretty amazing source of VSTS Profiler info.  Here is his post on command-line profiling.  The instructions he gives in that post should be used for startup-time profiling.  


However, when measuring actions after startup, slightly different steps are needed to factor out startup time.  Below are the steps I’ve been using for measuring post-startup actions:


Step-by-Step: Profiling WPF from the Command-Line


1.  Setup before the app has started. 


Doing this step before the app launches is very important!  If you don’t, managed code won’t be profiled and you’ll get an error similiar to this:


Warning VSP2321 : Managed code could not be profiled. Use VSPerfCLREnv.cmd to set the environment for managed code profiling


set PATH=%PATH%;”C:\Program Files\Microsoft Visual Studio 8\Team Tools\Performance Tools”


VSPerfClrEnv.cmd /sampleon


If you don’t do this, the /attach command in Step 2 won’t work.


vsperfcmd /start:SAMPLE /output:MyOutput.vsp


vsperfcmd /globaloff


These commands will initialize your environmental variables, and warm-up the profiler before profiling is started.  The last command will suspend profiling until you are ready to start profiling. 


2.  Profiling your application.


There are 2 ways to start profiling the application — attaching to a running application, or launching the application. 


Launching the application directly (to measure startup costs)


Sometimes, profiling can be very … challenging (to your sanity).  Learn this next lesson from me and save your juice for other problems.  Always attach to an application instead of launching it directly, -unless- your optimizing for startup time specifically.  If you don’t your profile will contain both startup costs and your post-startup action, and you won’t have a clue as to which is which .  If your interested in optimizing both startup time and some post-startup action , then use 2 seperate profiles.


To measure startup time, use the follow to commands:


      vsperfcmd /globalon


      vsperfcmd /launch:MyTest.exe


Use /globalon before launching the app so all of the startup costs are captured by the profiler.


Attaching to an application (to measure anything after startup)


First, launch the application FROM THE COMMAND LINE (the same one you used vsperfclrenv on).  Otherwise the environmental variables set in Step 1 won’t be picked up, and you’ll get that same error:


Warning VSP2321 : Managed code could not be profiled. Use VSPerfCLREnv.cmd to set the environment for managed code profiling


Run these commands to measure post-startup costs:


vsperfcmd /attach:MyTest.exe


vsperfcmd /globalon


This starts profiling & attaches the profiler to your already-running application.  We use /globalon after /attach so that any costs incurred during /attach aren’t included in the profile.


3.  Perform the action you want to profile


4.  Stop profiling


vsperfcmd /globaloff


First, we turn off profiling to ensure only the interesting action was profiled, and not shutdown.


kill MyTest.exe


The /shutdown switch waits for the app to exit, so kill the app before attempting shutdown.  You can also close it using the UI or Alt+F4.


vsperfcmd /shutdown.


End profiling.  After this step, the .VSP log specified to the /output parameter will be generated.


5.  Pack symbols


If your viewing the .VSP soley on the machine you used to gather the profile on, this step is optional.  Otherwise, make sure to pack symbols before moving the .VSP to another machine.


   xcopy /E  “C:\Documents and Settings\timothyc\My Documents\Visual Studio 2005\Projects\MyTest\MyTest\bin\Release\*.PDB” .


Copy all of the symbols for your project to the local directory.  I’ve found symbol packing to work -much- more consistently when symbols exist in the local directory.


      set _NT_SYMBOL_PATH=’WPF Symbol Server’


This command is optional for external folks who don’t have access to private WPF symbol servers.  A number of internal folks use this blog, so I’m mentioning it so they can make sure and maximize symbol information. 


   vsperfreport /summary:all /packsymbols MyOutput.VSP


 This last command performs the actual symbol packing, now that symbols have been setup.


Using Batch Files


Using a batch file to start & stop profiling is really important.  Not only does it minimize the performance impact of interacting with the command console, it helps ensure that results are reproducible by repeating the exact same steps in subsequent profiles.  Here is the batch file I use when profiling from the command line.


REM Initialize the VSTS Profiler


REM


set PATH=%PATH%;”C:\Program Files\Microsoft Visual Studio 8\Team Tools\Performance Tools”


call VSPerfClrEnv.cmd /sampleon


call vsperfcmd /start:SAMPLE /output:MyOutput.vsp


call vsperfcmd /globaloff


REM


REM Initialize my app


REM Use start.exe to avoid blocking the current command console


REM


start MyTest.exe


REM


REM Sleep for 25 seconds while my app starts up and I navigate through it


REM


sleep 25


REM


REM Start Profiling


REM


call vsperfcmd /attach:MyTest.exe


call vsperfcmd /globalon


REM


REM Record 20 seconds of the action


REM


sleep 20


REM


REM Stop Profiling


REM


call vsperfcmd /globaloff


kill MyTest.exe


call vsperfcmd /shutdown

Skip to main content