|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-16A1C613-288D-471C-8551-51B61290E28F" xml:lang="en"><title>Application |
|
13 Start-Up Time Optimization</title><shortdesc>It is important that phone users do not have to wait long for applications |
|
14 to start. This document summarizes the techniques for optimizing application |
|
15 start-up time.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
16 <section> <title>Introduction</title> <p>The techniques discussed |
|
17 in this document are limited in scope to application programming. In other |
|
18 words, they do not require modification of any core OS components or servers. |
|
19 Some of the techniques are general good practice and are useful to developers |
|
20 at all levels. </p> <p>The techniques can be summarized as follows:</p><ul> |
|
21 <li><p>Avoid causing unnecessary code to be executed as an effect of your |
|
22 code.</p></li> |
|
23 <li><p>Defer construction of objects, loading of dynamic libraries (for example, |
|
24 the application model), and starting servers until you need to use them.</p></li> |
|
25 <li><p>Write efficient code!</p></li> |
|
26 </ul><note>There is an inevitable trade-off between shortening the start-up |
|
27 time and introducing latency elsewhere in the application. For example, if |
|
28 you don’t connect to a server at start-up, you will have to do it later on, |
|
29 when the application needs to use the server. This may be overcome by a central |
|
30 component that coordinates background connections, or construction, such as |
|
31 the view server.</note></section> |
|
32 <section><title>Measure start-up time before you start optimizing</title><p>Do |
|
33 not assume you know which methods take the most time. Pay close attention |
|
34 to iterative and recursive operations. Many useful tools and techniques are |
|
35 available to help identify poorly performing code:</p><ul> |
|
36 <li><p>Software analysis tools, for instance <xref href="http://www.glowcode.com.dita">GlowCode</xref> and |
|
37 MetroWerks <xref href="http://www.metrowerks.com/MW/Develop/AMC/CodeTEST/default.htm.dita">CodeTEST</xref></p></li> |
|
38 <li><p>The Symbian profiling tool, profiler.exe, which is supplied on DevKits </p></li> |
|
39 <li><p>The RDebug class provides some profiling functions </p></li> |
|
40 <li><p>The TTime class can be used to time blocks of code, but beware of context |
|
41 switches, otherwise you may end up timing other threads!</p></li> |
|
42 <li><p>Deliberately slowing down suspect blocks of code can reveal whether |
|
43 or not optimizing it would bring a significant performance improvement. </p></li> |
|
44 </ul></section> |
|
45 <section><title>Defer construction of the application model and other data |
|
46 members</title><p>Many applications instantiate their components, for instance |
|
47 error handlers, dialogs and menus, during start-up. In turn, each of these |
|
48 components may instantiate other components, for instance menu resources and |
|
49 icons. This can bring some benefits, for instance reducing application complexity, |
|
50 revealing memory allocation problems at start-up rather than after the application |
|
51 has been running for some time and improving the runtime performance of the |
|
52 application. However, to minimize application start-up time, it is recommended |
|
53 to avoid this behavior. Your goal should be to only do what is immediately |
|
54 necessary during start-up. </p></section> |
|
55 <section><title>Draw the application as quickly as possible</title><p>During |
|
56 application start-up, only construct UI components that appear in the application’s |
|
57 initial view. This applies especially to the application's implementations |
|
58 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>. |
|
59 Do not read bitmaps, resources, or any other data associated with the UI from |
|
60 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>, |
|
61 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 |
|
62 called on all controls that must be drawn when the application is launched. |
|
63 Also ensure that the client-side window server command buffer is flushed by |
|
64 calling <xref href="GUID-09D06EF8-E231-3A76-A4F0-267B9CD83B54.dita"><apiname>Flush(</apiname></xref>) on the application's window server session. |
|
65 This ensures that there aren't any drawing commands left in the client-side |
|
66 buffer, after <xref href="GUID-0F226BB0-2D2F-3BD5-A439-C25F7DEACE85.dita"><apiname>DrawNow()</apiname></xref> has completed. </p></section> |
|
67 <section><title>Minimize the number of bitmaps used by GUI components</title><p>Often, |
|
68 when a large number of small images are required by an application, the overhead |
|
69 associated with loading each bitmap outweighs any benefit associated with |
|
70 their size. Some possible ways to avoid this are: </p><ul> |
|
71 <li><p>use text instead, </p></li> |
|
72 <li><p>for very simple graphics, draw directly using drawing primitives rather |
|
73 than loading a bitmap, </p></li> |
|
74 <li><p>concatenate many small bitmaps into one large bitmap file to reduce |
|
75 the need to search for and load multiple files.</p></li> |
|
76 </ul></section> |
|
77 <section><title>Reduce the number of redraws</title><p>Some GUI components |
|
78 redraw themselves every time their data changes. This may not always be necessary. |
|
79 Complicated GUI components should implement their <xref href="GUID-AC3B79CA-A2FE-395E-9BCE-4630AF6910AC.dita"><apiname>Draw()</apiname></xref> method |
|
80 to only update the area of the screen that has changed. For example, there |
|
81 is no point in redrawing a whole list box every time a new item is appended |
|
82 to it. In such cases, a GUI API should allow you to switch off redrawing. |
|
83 Beware of GUI methods that cause the object they are called upon to redraw |
|
84 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 |
|
85 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 |
|
86 use of <xref href="GUID-65BA28DB-77C6-3075-80E7-84E98780FD19.dita"><apiname>DrawNow(</apiname></xref>) can cause GUI flicker. For an explanation, |
|
87 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> |
|
88 <section><title>Use ROM-based bitmaps rather than filestore bitmaps</title><p>Uncompressed |
|
89 ROM-based bitmaps that can be used in place from ROM are approximately three |
|
90 times faster to use than filestore bitmaps. Using them can bring a significant |
|
91 reduction in application start-up time. </p><p>Specifying bitmap= instead |
|
92 of file= in the .OBY and .IBY files when building the ROM causes bitmaps to |
|
93 be uncompressed before inclusion in the ROM. Other bitmaps need to be uncompressed |
|
94 at runtime, which impacts performance. </p><p>The drawback of such bitmaps |
|
95 is that they are large (up to 3 times larger than file based) and cannot be |
|
96 compressed, although decompressing bitmaps should probably be avoided during |
|
97 start-up anyway due to the extra processing required. </p><p>If ROM space |
|
98 is limited, consider using such ROM-based bitmaps only if they are displayed |
|
99 during application start-up. </p></section> |
|
100 <section><title>Color depth matching</title><p>When bitmaps are drawn to the |
|
101 screen, optimum performance is achieved by ensuring that:</p><codeph>Bitmap |
|
102 color depth = Window color depth = Screen device color depth </codeph><p>If |
|
103 this is the case, no palette mapping between the different color depths is |
|
104 needed. On real hardware, this optimization has been found to improve drawing |
|
105 speed by up to ten times. However, in order to match the screen |
|
106 and window color depth, bitmaps may need to increase in size and so this optimization |
|
107 is only possible if the increase in ROM or RAM usage is acceptable. </p></section> |
|
108 <section><title>Minimize access to the file system</title><p>The file server |
|
109 can be a major bottleneck during start-up when virtually all threads are searching |
|
110 for and loading data, libraries and plug-ins. Therefore reducing file access |
|
111 is one of the most effective ways to improve performance. </p></section> |
|
112 <section><title>Minimize the use of resource files</title><p>Resource files |
|
113 are used for localization and allow modifications to be made to an application |
|
114 without the need to rebuild it, but they are expensive to use because they |
|
115 require access to the file system. </p></section> |
|
116 <section><title>Do not specify a default document filename for non document-based |
|
117 applications</title><p>Many applications on a smartphone do not need to use |
|
118 documents, for example Telephony, Contacts (this uses the contacts database), |
|
119 Browser and Messaging. </p><p>By not specifying a default document filename, |
|
120 hundreds of milliseconds can potentially be saved from such applications' |
|
121 start-up time. </p><p>If an application uses a document file, application |
|
122 start-up may involve the following steps: </p><ul> |
|
123 <li><p>reading the name of the last used document file from the application’s |
|
124 .ini file,</p></li> |
|
125 <li><p>opening the document file, or if one doesn't exist, creating a default |
|
126 document file, after reading its name from the application's resource file, </p></li> |
|
127 <li><p>writing the name of the last used file to the application’s .ini file |
|
128 (which is created if it doesn’t exist), </p></li> |
|
129 <li><p>writing an entry to the most recently used file list (mru.dat), </p></li> |
|
130 <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> |
|
131 </ul><p>The default document's name is read from the application's resource |
|
132 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 |
|
133 two ways of preventing the application from using a default document file: </p><ul> |
|
134 <li><p>Give the default document a NULL name in the resource file:</p><codeph>RESOURCE |
|
135 TBUF { buf=""; }</codeph></li> |
|
136 <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 |
|
137 zero the document name and return EFalse. This method is slightly more efficient |
|
138 because it avoids reading the default document name from the resource file |
|
139 altogether: </p><codeblock xml:space="preserve">TBool CMyAppUi::ProcessCommandParametersL(TApaCommand /*aCommand*/, TFileName& aDocumentName, const TDesC8& /*aTail*/){aDocumentName.Zero();return EFalse;}</codeblock></li> |
|
140 </ul></section> |
|
141 <section><title>Drive scanning</title><p>This can be a cause of unnecessary |
|
142 file server use. </p><p>To prevent excessive drive access and scanning, |
|
143 always specify a drive letter in file paths, if known. The omission of a drive |
|
144 letter will cause all available drives to be searched in the standard Symbian |
|
145 OS order, in which Z: is always searched last. </p></section> |
|
146 <section><title>Only make server requests if you need to</title><p> Server |
|
147 requests involve context switching and may cause the server to run instead |
|
148 of the application. In the worse case if you make a request to a server that |
|
149 has not yet been started you may cause the server to start. This will involve |
|
150 creating a new thread (and possibly process) and running any server initialization |
|
151 code.</p></section> |
|
152 <section><title>Use asynchronous server requests instead of synchronous server |
|
153 requests</title><p> Synchronous operations or methods (particularly for server |
|
154 requests) can cause general application slowness, and in particular, a significant |
|
155 reduction in responsiveness. Synchronous requests to servers mean your thread |
|
156 is waiting, so that no start-up progress is being made. </p><p>No 'Golden |
|
157 Rule' exists about when to avoid synchronous requests. However, if an asynchronous |
|
158 version of a method exists, it is a good indication that the synchronous method |
|
159 could potentially take some time. Whilst it may take a little extra effort |
|
160 to handle asynchronous versions of method calls, you should consider very |
|
161 carefully any decision to use the synchronous version. It’s often easier to |
|
162 change from using an asynchronous version to synchronous than vice versa. |
|
163 </p><p>Note that in some situations, you might know that the server is implementing |
|
164 your asynchronous request synchronously. If this is the case, and the server |
|
165 runs with a higher priority than your application, then both versions of the |
|
166 API may have the same performance. However, using the synchronous version |
|
167 in this case has the drawback that it relies upon knowledge of the server's |
|
168 implementation, which could potentially change. </p></section> |
|
169 <section><title>Do not repeatedly open and close connections to the same server</title><p> Opening |
|
170 a connection to a server is an expensive operation. If an application uses |
|
171 a server frequently then it should create one connection and leave it open |
|
172 until the application is destroyed. R classes declared as temporaries (on |
|
173 the stack, in other words) within a method may be a sign of this behavior. </p></section> |
|
174 </conbody></concept> |