Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to optimise application start-up time

[Top]


Introduction

This document summarises the techniques for improving application start-up time.

The techniques discussed are limited in scope to application programming. In other words, they do not require modification of any core OS components or servers. Some of the techniques are general good practice and are useful to developers at all levels.

The techniques can be summarised as follows:

Note that there is an inevitable trade-off between shortening the start-up time and introducing latency elsewhere in the application. For example, if you don’t connect to a server at start-up, you will have to do it later on, when the application needs to use the server. This may be overcome by a central component that co-ordinates background connections, or construction, such as the view server.

[Top]


General optimisation techniques


Measure start-up time before you start optimising

Do not assume you know which methods take the most time. Pay close attention to iterative and recursive operations. Many useful tools and techniques are available to help identify poorly performing code:


Defer construction of the application model and other data members

Many applications instantiate their components, for instance error handlers, dialogs and menus, during start-up. In turn, each of these components may instantiate other components, for instance menu resources and icons. This can bring some benefits, for instance reducing application complexity, revealing memory allocation problems at start-up rather than after the application has been running for some time and improving the runtime performance of the application. However, to minimise application start-up time, it is recommended to avoid this behaviour. Your goal should be to only do what is immediately necessary during start-up.


Recursion and iteration

Whenever recursion or iteration occurs, there is usually scope for significant speed improvements, especially in the most commonly used components. This is obvious but is often overlooked when looking for easy performance gains.

[Top]


GUI optimisations


Draw the application as quickly as possible

During application start-up, only construct UI components that appear in the application’s initial view. This applies especially to the application's implementations of CXxxApplication::CreateDocumentL(), CXxxDocument::ConstructL() and CXxxDocument::CreateAppUiL(), all of which are called before CXxxAppUi::ConstructL(). Do not read bitmaps, resources, or any other data associated with the UI from files unless it is necessary.

In CXxxAppUi::ConstructL(), make sure ActivateL() and DrawNow() are called on all controls that must be drawn when the application is launched. Also ensure that the client-side window server command buffer is flushed by calling Flush() on the application's window server session. This ensures that there aren't any drawing commands left in the client-side buffer, after DrawNow() has completed.


Minimise the number of bitmaps used by GUI components

Often, when a large number of small images are required by an application, the overhead associated with loading each bitmap outweighs any benefit associated with their size. Some possible ways to avoid this are:


Reduce the number of redraws

Some GUI components redraw themselves every time their data changes. This may not always be necessary. Complicated GUI components should implement their Draw() method to only update the area of the screen that has changed. For example, there is no point in redrawing a whole list box every time a new item is appended to it. In such cases, a GUI API should allow you to switch off redrawing. Beware of GUI methods that cause the object they are called upon to redraw itself.

Use CCoeControl::DrawDeferred() in preference to CCoeControl::DrawNow() if possible, because excessive use of DrawNow() can cause GUI flicker. For an explanation, see the documentation for CCoeControl::DrawDeferred().


Use ROM-based bitmaps rather than filestore bitmaps

Uncompressed ROM-based bitmaps that can be used in place from ROM are approximately three times faster to use than filestore bitmaps. Using them can bring a significant reduction in application start-up time.

Specifying bitmap= instead of file= in the .OBY and .IBY files when building the ROM causes bitmaps to be uncompressed before inclusion in the ROM. Other bitmaps need to be uncompressed at runtime, which impacts performance.

The drawback of such bitmaps is that they are large (up to 3 times larger than file based) and cannot be compressed, although decompressing bitmaps should probably be avoided during start-up anyway due to the extra processing required.

If ROM space is limited, consider using such ROM-based bitmaps only if they are displayed during application start-up.


Colour depth matching

When bitmaps are drawn to the screen, optimum performance is achieved by ensuring that:

Bitmap colour depth = Window colour depth = Screen device colour depth

If this is the case, no palette mapping between the different colour depths is needed. On real hardware, this optimisation has been found to improve drawing speed by up to 10 times. However, in order to match the screen and window colour depth, bitmaps may need to increase in size and so this optimisation is only possible if the increase in ROM or RAM usage is acceptable.

[Top]


File server optimisations


Minimise access to the file system

The file server can be a major bottleneck during start-up when virtually all threads are searching for and loading data, libraries and plug-ins. Therefore reducing file access is one of the most effective ways to improve performance.


Minimise the use of resource files

Resource files are used for localisation and allow modifications to be made to an application without the need to rebuild it, but they are expensive to use because they require access to the file system.


Do not specify a default document filename for non document-based applications

Many applications on a smartphone do not need to use documents, for example Telephony, Contacts (this uses the contacts database), Browser and Messaging.

By not specifying a default document filename, hundreds of milliseconds can potentially be saved from such applications' start-up time.

If an application uses a document file, application start-up may involve the following steps:

The default document's name is read from the application's resource file by CEikAppUi::ProcessCommandParametersL(). There are two ways of preventing the application from using a default document file:


Drive scanning

This can be a cause of unnecessary file server use.

To prevent excessive drive access and scanning, always specify a drive letter in file paths, if known. The omission of a drive letter will cause all available drives to be searched in the standard Symbian OS order, in which Z: is always searched last.

[Top]


Using servers


Only make server requests if you need to

Server requests involve context switching and may cause the server to run instead of the application. In the worse case if you make a request to a server that has not yet been started you may cause the server to start. This will involve creating a new thread (and possibly process) and running any server initialisation code.


Use asynchronous server requests instead of synchronous server requests

Synchronous operations or methods (particularly for server requests) can cause general application slowness, and in particular, a significant reduction in responsiveness. Synchronous requests to servers mean your thread is waiting, so that no start-up progress is being made.

No 'Golden Rule' exists about when to avoid synchronous requests. However, if an asynchronous version of a method exists, it is a good indication that the synchronous method could potentially take some time. Whilst it may take a little extra effort to handle asynchronous versions of method calls, you should consider very carefully any decision to use the synchronous version. It’s often easier to change from using an asynchronous version to synchronous than vice versa.

Note that in some situations, you might know that the server is implementing your asynchronous request synchronously. If this is the case, and the server runs with a higher priority than your application, then both versions of the API may have the same performance. However, using the synchronous version in this case has the drawback that it relies upon knowledge of the server's implementation, which could potentially change.


Do not repeatedly open and close connections to the same server

Opening a connection to a server is an expensive operation. If an application uses a server frequently then it should create one connection and leave it open until the application is destroyed. R classes declared as temporaries (on the stack, in other words) within a method may be a sign of this behaviour.