Symbian3/SDK/Source/GUID-16A1C613-288D-471C-8551-51B61290E28F.dita
author Dominic Pinkman <Dominic.Pinkman@Nokia.com>
Thu, 21 Jan 2010 18:18:20 +0000
changeset 0 89d6a7a84779
permissions -rw-r--r--
Initial contribution of Documentation_content according to Feature bug 1266 bug 1268 bug 1269 bug 1270 bug 1372 bug 1374 bug 1375 bug 1379 bug 1380 bug 1381 bug 1382 bug 1383 bug 1385

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-16A1C613-288D-471C-8551-51B61290E28F" xml:lang="en"><title>Application
Start-Up Time Optimization</title><shortdesc>It is important that phone users do not have to wait long for applications
to start. This document summarizes the techniques for optimizing application
start-up time.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<section>       <title>Introduction</title>       <p>The techniques discussed
in this document 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. </p>     <p>The techniques can be summarized as follows:</p><ul>
<li><p>Avoid causing unnecessary code to be executed as an effect of your
code.</p></li>
<li><p>Defer construction of objects, loading of dynamic libraries (for example,
the application model), and starting servers until you need to use them.</p></li>
<li><p>Write efficient code!</p></li>
</ul><note>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 coordinates background connections, or construction, such as
the view server.</note></section>
<section><title>Measure start-up time before you start optimizing</title><p>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:</p><ul>
<li><p>Software analysis tools, for instance <xref href="http://www.glowcode.com.dita">GlowCode</xref> and
MetroWerks <xref href="http://www.metrowerks.com/MW/Develop/AMC/CodeTEST/default.htm.dita">CodeTEST</xref></p></li>
<li><p>The Symbian profiling tool, profiler.exe, which is supplied on DevKits </p></li>
<li><p>The RDebug class provides some profiling functions </p></li>
<li><p>The TTime class can be used to time blocks of code, but beware of context
switches, otherwise you may end up timing other threads!</p></li>
<li><p>Deliberately slowing down suspect blocks of code can reveal whether
or not optimizing it would bring a significant performance improvement. </p></li>
</ul></section>
<section><title>Defer construction of the application model and other data
members</title><p>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 minimize application start-up time, it is recommended
to avoid this behavior. Your goal should be to only do what is immediately
necessary during start-up. </p></section>
<section><title>Draw the application as quickly as possible</title><p>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 <xref href="GUID-05A12A50-93A3-3F3E-842F-81EF47D78F7F.dita#GUID-05A12A50-93A3-3F3E-842F-81EF47D78F7F/GUID-172521B0-E7C8-3214-AA4D-814A9C98216C"><apiname>CXxxApplication::CreateDocumentL()</apiname></xref>, <xref href="GUID-8001206A-3B19-381F-96F6-350336FDFBF2.dita#GUID-8001206A-3B19-381F-96F6-350336FDFBF2/GUID-453AFFB0-6711-3881-97E6-0BB9E5185E06"><apiname>CXxxDocument::ConstructL()</apiname></xref> and <xref href="GUID-8001206A-3B19-381F-96F6-350336FDFBF2.dita#GUID-8001206A-3B19-381F-96F6-350336FDFBF2/GUID-DCC1BAD5-95AB-3308-9132-2780852BA913"><apiname>CXxxDocument::CreateAppUiL()</apiname></xref>, all of which are called before <xref href="GUID-3C72B6B6-F1B3-3C36-B69A-5074E5EDC32A.dita#GUID-3C72B6B6-F1B3-3C36-B69A-5074E5EDC32A/GUID-5C26B1AB-6917-3133-9CD8-34AFCA9524B9"><apiname>CXxxAppUi::ConstructL()</apiname></xref>.
Do not read bitmaps, resources, or any other data associated with the UI from
files unless it is necessary.</p><p>In <xref href="GUID-3C72B6B6-F1B3-3C36-B69A-5074E5EDC32A.dita#GUID-3C72B6B6-F1B3-3C36-B69A-5074E5EDC32A/GUID-5C26B1AB-6917-3133-9CD8-34AFCA9524B9"><apiname>CXxxAppUi::ConstructL()</apiname></xref>,
make sure <xref href="GUID-6965379F-00B9-38DB-9AF3-9DAD55DEBBB7.dita"><apiname>ActivateL()</apiname></xref> and <xref href="GUID-0F226BB0-2D2F-3BD5-A439-C25F7DEACE85.dita"><apiname>DrawNow()</apiname></xref> 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 <xref href="GUID-09D06EF8-E231-3A76-A4F0-267B9CD83B54.dita"><apiname>Flush(</apiname></xref>) on the application's window server session.
This ensures that there aren't any drawing commands left in the client-side
buffer, after <xref href="GUID-0F226BB0-2D2F-3BD5-A439-C25F7DEACE85.dita"><apiname>DrawNow()</apiname></xref> has completed. </p></section>
<section><title>Minimize the number of bitmaps used by GUI components</title><p>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: </p><ul>
<li><p>use text instead, </p></li>
<li><p>for very simple graphics, draw directly using drawing primitives rather
than loading a bitmap,  </p></li>
<li><p>concatenate many small bitmaps into one large bitmap file to reduce
the need to search for and load multiple files.</p></li>
</ul></section>
<section><title>Reduce the number of redraws</title><p>Some GUI components
redraw themselves every time their data changes. This may not always be necessary.
Complicated GUI components should implement their <xref href="GUID-AC3B79CA-A2FE-395E-9BCE-4630AF6910AC.dita"><apiname>Draw()</apiname></xref> 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.</p><p>Use <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita#GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160/GUID-811046A4-4272-3B29-80D9-CB897C4E1DD0"><apiname>CCoeControl::DrawDeferred(</apiname></xref>) in preference
to <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita#GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160/GUID-70FF46AE-5ACC-36F1-97F0-CBD847779C19"><apiname>CCoeControl::DrawNow(</apiname></xref>) if possible, because excessive
use of <xref href="GUID-65BA28DB-77C6-3075-80E7-84E98780FD19.dita"><apiname>DrawNow(</apiname></xref>) can cause GUI flicker. For an explanation,
see the documentation for <xref href="GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160.dita#GUID-B06F99BD-F032-3B87-AB26-5DD6EBE8C160/GUID-9FB682AC-0209-302A-83F3-7BCB1162B998"><apiname>CCoeControl::DrawDeferred()</apiname></xref>. </p></section>
<section><title>Use ROM-based bitmaps rather than filestore bitmaps</title><p>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.   </p><p>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.   </p><p>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.   </p><p>If ROM space
is limited, consider using such ROM-based bitmaps only if they are displayed
during application start-up. </p></section>
<section><title>Color depth matching</title><p>When bitmaps are drawn to the
screen, optimum performance is achieved by ensuring that:</p><codeph>Bitmap
color depth = Window color depth = Screen device color depth </codeph><p>If
this is the case, no palette mapping between the different color depths is
needed. On real hardware, this optimization has been found to improve drawing
speed by up to ten times. However, in order to match the screen
and window color depth, bitmaps may need to increase in size and so this optimization
is only possible if the increase in ROM or RAM usage is acceptable. </p></section>
<section><title>Minimize access to the file system</title><p>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. </p></section>
<section><title>Minimize the use of resource files</title><p>Resource files
are used for localization 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. </p></section>
<section><title>Do not specify a default document filename for non document-based
applications</title><p>Many applications on a smartphone do not need to use
documents, for example Telephony, Contacts (this uses the contacts database),
Browser and Messaging.   </p><p>By not specifying a default document filename,
hundreds of milliseconds can potentially be saved from such applications'
start-up time.   </p><p>If an application uses a document file, application
start-up may involve the following steps: </p><ul>
<li><p>reading the name of the last used document file from the application’s
.ini file,</p></li>
<li><p>opening the document file, or if one doesn't exist, creating a default
document file, after reading its name from the application's resource file, </p></li>
<li><p>writing the name of the last used file to the application’s .ini file
(which is created if it doesn’t exist),  </p></li>
<li><p>writing an entry to the most recently used file list (mru.dat), </p></li>
<li><p>additional document-related processing within <xref href="GUID-96CA3B4B-993F-36C0-9A5B-DF5CC74EE20E.dita#GUID-96CA3B4B-993F-36C0-9A5B-DF5CC74EE20E/GUID-E2A40307-6EB6-3ABC-B97A-63B77F565CCF"><apiname>CEikonEnv::ConstructAppFromCommandLineL()</apiname></xref>. </p></li>
</ul><p>The default document's name is read from the application's resource
file by <xref href="GUID-1185F595-0488-3E93-8D60-6B3A1A3AC32E.dita#GUID-1185F595-0488-3E93-8D60-6B3A1A3AC32E/GUID-5D851D0B-6399-3BD8-ADB5-63AD48494D47"><apiname>CEikAppUi::ProcessCommandParametersL()</apiname></xref>. There are
two ways of preventing the application from using a default document file: </p><ul>
<li><p>Give the default document a NULL name in the resource file:</p><codeph>RESOURCE
TBUF { buf=""; }</codeph></li>
<li><p>Override <xref href="GUID-1185F595-0488-3E93-8D60-6B3A1A3AC32E.dita#GUID-1185F595-0488-3E93-8D60-6B3A1A3AC32E/GUID-5D851D0B-6399-3BD8-ADB5-63AD48494D47"><apiname>CEikAppUi::ProcessCommandParametersL()</apiname></xref> to
zero the document name and return EFalse. This method is slightly more efficient
because it avoids reading the default document name from the resource file
altogether: </p><codeblock xml:space="preserve">TBool CMyAppUi::ProcessCommandParametersL(TApaCommand /*aCommand*/, TFileName&amp; aDocumentName, const TDesC8&amp; /*aTail*/){aDocumentName.Zero();return EFalse;}</codeblock></li>
</ul></section>
<section><title>Drive scanning</title><p>This can be a cause of unnecessary
file server use.   </p><p>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. </p></section>
<section><title>Only make server requests if you need to</title><p> 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 initialization
code.</p></section>
<section><title>Use asynchronous server requests instead of synchronous server
requests</title><p> 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.   </p><p>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. 
 </p><p>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. </p></section>
<section><title>Do not repeatedly open and close connections to the same server</title><p> 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 behavior. </p></section>
</conbody></concept>