So, Rico beat me to the punch: http://blogs.msdn.com/ricom/archive/2006/08/03/688019.aspx

 

As we have seen in the previous entry it is nice that the VSTS Profiler team has provided a tool which converts their .VSP files into something which is more easily readable by other programs. While I was working on CLR oerformance last year I spent a lot of time playing with the output of the VSTS Profiler before the UI pieces were ready, so I spent a lot of time using the data in the .CSV files to diagnose problems. After just a short amount of time doing this by hand I decided to go ahead and automate the process, I created a number of utilities to parse the output CSV files and find some interesting information. In that first rev you basically ha d to run the application anytime you wanted to change the inputs to the query (different string, different cutoffs for various things, etc.). It didn't take too long to realize that this wasn't going to scale, and PerfConsole was born...

What we can see above are some of the basics of PerfConsole's command syntax; overall it strives to mix some of the console module that cmd.exe or Windows PowerShell has with what is more or less a domain specifica language for interpreting profile data. There are a number of commands which are included in the base package which include the following which we can see above:

- load: loads a profile from disk, commonly you specify a .VSP file and PerfConsole will look for the (required) associated .CSV files which were generated either from the "export" function in VS or using the command line as outlined here.

- functions: takes a profile as input and returns the piece that corresponds to a list of functions which were seen in the profile with Inclusive and Exclusive times.

- modules: takes a profile as input and returns the piece that contains a list of modules which were seen in the profile with Inclusive and Exclusive times.

- sort: takes in a list and returns a sorted list ordered by some property (in this case "ex" is shorthand for "ExclusivePercentage")

- top: takes in a list and returns a subset of that list including X elements starting at element 0

Through the example above we can start to see the basic syntax of using PerfConsole: you use the '|' to connect statements where each statement (reading left to right) has input from the return value of the previous statement and the parameters specified. Like Windows PowerShell when things are passed from left to right they are full fledged .Net objects, and PerfConsole can use those objects to do some type checking as you go in order to tell you if you're combining commands in unsupported ways.

Incidentally I initially tried really hard to reverse the execution order and instead execute from right to left, it made for statements that read like a sentance "top 5 | sort ex | functions @board_ngen" == "get me the top 5 exclusive functions in @board_ngen"; however the people internally revolted and said that if that is what I wanted I couldn't overload '|' to do it.

As a side effect (or design point) of the way that PerfConsole passes objects between statements I have been able to implement a very powerful help system, for instance at any point you're able to pipe the result of any statement or set of statements to '?' and it will tell you the resulting data type and which commands will accept that type as a input (in a strongly typed manner). For instance:

> functions @board_ngen | ?
Data type is: PerfConsole.Data.FunctionSummaryData

This data type can be input to the following commands:

bottom
count
find
getitem
getproperty
sort
top
trim
timebytype
partition

Here we see that the functions command returns a FunctionSummaryData object which can be input to a number of other commands, including the top and sort commands. Here we also see that functions has this wierd "@board_ngen" parameter, in PerfConsole @ denotes a temporary (you can create these using the save command), and the temporary named "board_ngen" is the profile that I've imported for this demo.

Help also works well with commands. For instance:

> ? sort
Sort a ISortable (e.g. FunctionSummary, ModuleSummary). Each type has its own
sort types (e.g. 'name', 'address', 'exclusive', etc...).

Usage:
ISortable | sort <field:SortField> | ISortable
ISortable | sort <field:SortField> <direction:SortDirection> | ISortable

Have enum paramters:
SortDirection { Ascending, Descending }
SortField { Name, ExclusivePercentage, InclusivePercentage, Address }

Here we can see that we are able to see that the sort command takes as input something which implements ISortable (which by inference from the previous help output we believe that FunctionSummaryData does), it also can take up to two parameters which are values of the enum SortField and SortDirection (these are allowed to be shortened arbitrarially so long as they remain disabiguated from their peers). As a return value sort specifies that it returns an ISortable, if we pipe the return value from sort to the help we see:

> functions @board_ngen | sort ex | ?
Data type is: PerfConsole.Data.FunctionSummaryData

This indicates that sort actually returns a FunctionSummaryData (which implements ISortable), behind the scenes the sort command clones the original FunctionSummaryData and returns the modified copy.

 

Note that for simplicity's sake I've used PerfConsole with the /console command line option which causes results to show in the console, the default is to show results as HTML which you can click around to do more queries and such, in fact, before I end this blog entry which has already managed to get too long I'll show you Rico's favorite command:

> calltree @board_ngen | trim in > 5 | compacttree

 

Anyway, that's a primer on using PerfConsole, please download it here. When you start it up, the ?? command will open a longer document which should hopefully get you started quickly.