The EQATEC Profiler

This is a code profiler for .NET Compact Framework applications. Key features are:

  • Code profiler for optimizing your application's speed/performance, not a memory profiler
  • Very low overhead; typically 30% longer runtime and 30% extra codesize
  • All .NET 2.0/3.5, Full and Compact Framework applications can be profiled
  • Command-line version can integrate profiling into your autobuild
  • Precise instrumentation, as opposed to sampling profilers
  • Will profile methods, not individual statements
  • Full call-graph details are reported
  • 100% free for all to use

Visit http://www.eqatec.com/tools/profiler to download the full package, including the demo-app "Bubbles". And don't hesitate to contact tools@eqatec.com if you have questions or suggestions.

Quick guide to profiling

The profiler works by injecting extra timing-code into you existing assembly-files. At runtime this extra code measures the performance of every method. When you application stops, or during execution if you wish, you get a performance report.

How to profile your assemblies

You will use the profiler in four steps:

  1. Compile your application like normally, or simply pick any existing application
  2. Use the profiler to inject timing code into all the application's assemblies
  3. Run the modified application on your PC or device
  4. Use the viewer to view the report

That's it. That is all you need to do. You can try it out now on the demo-app, "Bubbles", or on any full .NET application you have installed. We often profile NASA's free "World Wind" app because it's tremendously big and therefore a good exercise for the profiler.

The next sections will describe these four steps.


Step 1: Compile your application

You don't need to do anything special to your application. Just compile it.

If you want better control of when profile-snapshots are taken, other than at application exit, you can do this: 1) include a reference to the runtime-module and 2) make the profiler dump reports when you want to. In this example we take a profiler snapshot when we double-click our application's header:

Use the runtime-API to dump snapshots at will

A generic version of the runtime-module is included in the installation (...\RuntimeDLL\EQATECProfilerRuntime.dll) specifically for the purpose of using as a reference. You'll most likely also want to check that DLL into your source control system.

It is also possible to add attributes to prevent methods from being profiled or appearing in the runtime-report. Profiled apps normally run fast enough, but it's there if you really need it:

Use attributes for finer profiling-control

"HideAtRuntime" means that this method's activities will not be reported at runtime. "SkipInstrumentation" avoids profiling this method entirely. If you specify the attribute for an class it takes effect on every method in that class.


Step 2: Profile your application

Profile your compiled assemblies as shown below:

Profile your application's assembly-files

A profiled assembly is typically 30% larger than the original and runs 30% slower. Normally you will just profile all of your assembly-files, but sometimes you would like to be more particular - for instance, if

  • your device has no room for that extra code
  • an assembly-file is highly time-critical and cannot stand the extra runtime-overhead
  • you're only interested in profiling a specific part (a few DLLs) of your application

The "extremely tiny, tiny methods" are methods that are 3-5 MSIL-instructions long and do nothing but get/set a real variable. Profiling a method adds about 80 MSIL-instructions; quite much to run just to time 3-5 instructions. The most correct and useful setting is therefore to skip, not profile, these tiny methods. The only time where it might make sense is if you wish to check that the method is really called (use callcount only for that) or if you simply wish these methods to be reported just like any other method (use full info, but don't place too much trust in the timing numbers).

An alternative to the GUI-profiler is the command-line version, EQATECProfilerCmd, available in the registered version. Use it to profile your code automatically, e.g. in your autobuild or as a post-build event. For convenience you should include a reference to the EQATECProfilerRuntime.dll in your project, so Visual Studio will automatically deploy it to your device.

Profiling your assemblies in a post-build step

Note: It is important that you profile all your application's assemblies together in one step, rather than individually one at a time. This is because the runtime-module, EQATECProfilerRuntime.dll, is generated each time to only care for methods in the selected, profiled assemblies.


Step 3: Deploy and run your application

The profiler will dump a report when your application exits, or at your request as explained earlier.

The report is called "profiler-timestamp.log.xml", e.g. profile-20080422-182342.log.xml from April 22th 2008, at 18:23:42. The report is saved to the first available of these locations: "\Storage Card", "\SD Card", "\Temp", and "\". So if your device has an SD-Card you can get the report out of it that way, which is quite handy.


Step 4: View the report

Ahh! The fruit of your labour. Finally, time to start finding performance bottlenecks!

Profile your application's assembly-files

You browse the methods by selecting them in the upper list or in the lower call-graph view. Follow the highest total time to find performance bottlenecks.

The view may seem complex, but is actually quite simple:

  • The upper list view show the grand total for each method: how many times it was called during this run and how long that took.
  • The lower call graph show the details of the selected method. The neighbor columns, "called by" and "called into", will show numbers related to the particular calls into and from the selected method. In the above example the get_TimeSimulator-method has been called 246 times from the selected get_Now method, for a total of 179ms. But get_TimeSimulator might have been called by other methods too; in this view we're focusing on get_Now, so to get the full picture of get_TimeSimulator's performance you should select that method instead.
  • The yellow bars show how much time each caller spends calling the selected method. Some caller's calls may be cheap while others are expensive. All the yellow bars add up to 100%.
  • The red bars show how much time is spent internally in the selected method and by the methods it calls. Those figures add up to 100%.
  • If a method is still running its timing will be shown with a + in front of it. This only happens if you take snapshots during your applications lifetime. What it means is that currently the reported internal execution time may be too low, as the latest call to the method has not yet completed.


Known limitations

This is a list of known limitations and problems. We're working on fixing these.

  • Recursive methods is reported as sum of the calls. The viewer should be more clever in this respect.
  • Blocking methods, such as Read(), will be counted as the total time, including the time the thread spends being descheduled and waiting for the call to complete. For now, you will have to recognize and judge situations like this manually.
  • No debug information is available for the profiled assemblies. It means that you cannot debug the profiled versions - but you would probably not like to do that, anyway.
  • No Visual Studio integration yet. We are looking into providing an add-in that will make it even easier to enable profiling your solution's assembly files.
  • No full method signature is displayed yet. So if you have several overloaded methods by the same name, or use generic methods, you cannot easily distinguish them as their signature (the methods's parameter list) is not displayed anywhere.
  • Only defined methods are currently profiled, not referenced ones. So all the methods that your application itself defines will be profiled, but not System.* etc.


Contact

The profiler is a work in progress. Your input is most welcome: if you have any problems or suggestions then please let us know.

Visit our website at http://www.eqatec.com
Send us an email at tools@eqatec.com

If you experience a bug, such as your profiled program not working or throwing an exception, then maybe we can help. We will most likely ask you to:

  1. First of all, check if there's maybe a newer profiler version available
  2. If not then please report the problem in our forum, or by mail
  3. Next, see if you can reproduce the problem on a smaller scale and send us a source example
  4. Or, submit as much info about the problem as possible; call-stack, types involved etc
  5. Or, submit the offending assembly-files to us
  6. Or, submit your entire offending source code project to us

If you'd like professional assistance in performance-tuning or improving your .NET CF application then don't hesitate to contact us, either. Because after all, doing hardcore embedded programming for clients is what we do for a living here at EQATEC.

Best regards,
the EQATEC tools team