Chapter 7. Optimizing for Performance

In web-based server applications, performance optimization is understandably a very necessary part of the software development lifecycle—after all, you are writing code to service hundreds of users at the same time. However, in a single user environment, such as the mobile device, you might wonder if this is necessary.

The truth is, sometimes mobile users may not need applications that run faster, but applications that respond faster. A mobile device has hardware limitations that will always place it behind the PC in terms of power and speed, so it will never be expected to number crunch or load data as fast as the PC can. By designing your mobile application so that it will be constantly and highly responsive to user input, it can make up for its limitations by providing a more fluid user experience.

In this chapter, you will learn how to write faster .NET CF code that facilitates responsive user interfaces. You will cover the following:

  • How to measure code performance
  • How to measure application performance statistics
  • How to optimize database performance through data caching and indexes
  • How to use the GZIP compression library provided by Microsoft to compress data for more efficient data transfer
  • The best practices to adopt when manipulating strings, WinForms, XML, and files in the .NET Compact Framework
  • An overview of how garbage collection in the .NET Compact Framework works

Measuring performance

Before you can optimize your code for performance, you obviously need to know if it is underperforming in the first place. You can measure performance at two basic levels—at the code level and at the application level.

At the code level, developers typically use timers in order to time sections of code and to then display the time taken for the piece of code to execute. At the application level, the developer might need to know, for instance, how much memory an application has been consuming or how many times garbage was collected during its lifetime.

In the following sections, we will explore how you can set up your code and application to collect this diagnostic information.

Measuring .NET CF code performance

The most basic way to measure the performance of a piece of code is to:

  1. Capture the start time.
  2. Perform the action.
  3. Capture the end time.
  4. Calculate the difference (delta).

There are a few ways to capture time. First, you have the Environment.TickCount .NET method (which is based on the Win32 API GetTickCount() method). It returns the amount of time (in milliseconds) that has passed since the device booted. However, there are two immediate problems with Environment.TickCount:

  • It has poor accuracy (the variance can be up to 500 milliseconds)
  • It has a limited size—for devices that have been running for a long time, the tick count may overflow, and end up being a negative number

The better (and more accurate) way to measure time would be to use a high resolution timer. The QueryPerformanceCounter method returns the current value of the high resolution performance counter, and the QueryPerformanceFrequency method the number of counts per second. To measure performance, you can:

  1. Call QueryPerformanceCounter to capture the start time.
  2. Perform the action.
  3. Call QueryPerformanceCounter again to capture the end time.
  4. Calculate the difference (delta) between these two values and divide it by the frequency retrieved via QueryPerformanceFrequency. This will return the amount of seconds elapsed. You can also retrieve the time in milliseconds by performing a simple conversion.

Let's build a class to do this. Create a new class called PerfTimer and add it to the CRMLiveFramework project. You will need two functions: Start and Stop, to signal the capturing of the start time and corresponding stop time. The Stop function will return the amount of time elapsed (in milliseconds).

The QueryPerformanceCounter and QueryPerformanceFrequency functions are Win32 API functions and do not have any .NET framework equivalent. You will thus need to declare these external functions using the DllImport keyword. The code for the PerfTimer class follows:

using System;
using System.Runtime.InteropServices;
public class PerfTimer
{
[DllImport("coredll.dll", EntryPoint =
"QueryPerformanceCounter")]public static extern int
QueryPerformanceCounter(long perfCounter);
[DllImport("coredll.dll", EntryPoint =
"QueryPerformanceFrequency")]public static extern int
QueryPerformanceFrequency(long frequency);
private long _timerFreq;
private long _startTime;
private long _endTime;
public PerfTimer()
{
if (QueryPerformanceFrequency(_timerFreq) == 0)
{
throw (new Exception("Could not retrieve timer
frequency"));
}
}
public void StartTimer()
{
if (QueryPerformanceCounter(_startTime) == 0)
{
throw (new Exception("Could not retrieve timer start time"));
}
}
public long StopTimer()
{
if (QueryPerformanceCounter(_endTime) == 0)
{
throw (new Exception("Could not retrieve timer end time"));
}
return ((_endTime - _startTime) * 1000) / _timerFreq;
}
}

Now let's see how you can use this class. In the SalesForceApp project, open the AccountDetails form. Look for the RefreshPage method. The GetAccountsByType method is called here—let's measure the time it takes for the dataset to be retrieved from this method call. Add the lines highlighted in the following code:

private void RefreshPage()
{
try
{
PerfTimer _timer = new PerfTimer();
_timer.StartTimer();
_accounts =
GlobalArea.Application.GetAccountsByType(_type,
_totalRecords, pgPager.CurrentPage, _recordsPerPage,
_SortColumn, _SortOrder);
MessageBox.Show("Data retrieved in :" +
_timer.StopTimer() + " milliseconds");
dgAccounts.DataSource = _accounts;
dgAccounts.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

Run the application and try opening the Leads Listing page. The message shown in the next screenshot will be immediately displayed.

Measuring .NET CF code performance

Capturing application performance statistics

In the preceding section, you've learned how to measure performance at the code level. However, you can also retrieve performance statistics at the application's working-set level via internal counters maintained by the .NET Compact Framework. This includes, for example, the amount of memory allocated or deallocated during the application's execution.

To activate these performance counters, you will first need to enable a key in the registry of your mobile device. Windows Mobile does not come with a tool to edit the registry, so you will either need to get a third-party tool or do it remotely from your desktop using the bundled CE Remote Tools package from Microsoft.

Launch the ccregedt.exe application from this location on your desktop:

Program FilesCE Remote Tools5.01inccregedt.exe

You should be able to see a window that allows you to choose a target device. Choose the Windows Mobile 6 Professional Emulator device.

Capturing application performance statistics

This will launch the emulator. At the same time, you will be able to edit the registry details for the emulator device using an interface that is similar to the desktop-based regedit.exe tool.

Capturing application performance statistics

Expand the Windows Mobile 6 Professional Emulator node and create a new key named PerfMonitor under the following key:

HKEY_LOCAL_MACHINESoftwareMicrosoft.NET CompactFramework

In this key, create a DWORD value with the name Counters, and set its value to 1. This will signal the framework to generate a .Stat file whenever a managed application executes. If you wish to disable capturing of performance statistics, set this value to 0. This key and value can be seen in the following screenshot:

Capturing application performance statistics

You can save the emulator's state at this point. Run the sales force application now by navigating to its folder. After the application launches, close and exit the application. You will now notice that a new file with the name of your application and the .stat extension (for example, SalesForceApp.stat) has been automatically generated in the root folder of the device.

Copy this file to your desktop and open it using Microsoft Excel. You will be able to see a list of performance counters and their values. Through this set of statistics, you can determine the total amount of different resources used throughout your application. If, for instance, you wanted to reduce the memory footprint size of your application, you could use this set of statistics as a gauge for memory consumption.

You can also view the .stat file using the .NET Compact Framework Remote Performance Monitor tool at the following location:

Program FilesMicrosoft.NETSDKCompactFrameworkv2.0inNetCFRPM.exe

You can open a .stat file from the File | Open menu in the tool. The Remote Performance Monitor displays a more comprehensive view of the counters together with brief explanations of each counter.

Capturing application performance statistics

You can read about each of these counters listed in the previous section in detail at the following location:

http://msdn.microsoft.com/en-us/library/ms172525.aspx

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.160.137