Performance Tips for Symbian Applications

download Performance Tips for Symbian Applications

of 40

Transcript of Performance Tips for Symbian Applications

  • 8/14/2019 Performance Tips for Symbian Applications

    1/40

  • 8/14/2019 Performance Tips for Symbian Applications

    2/40

    Secure your route to market

    Symbian Signed is an industry-backed schemethat allows Symbian OS software developers toobtain a digital signature for their applications.To be Symbian Signed applications must passvarious standardized tests. Some networkoperators and phone manufacturers (e.g., Orange,

    Nokia and Sony Ericsson) now require that C++and AppForge MobileVB/Crossfire applicationsmust be signed if they are to be distributedthrough their channels.

    Applications that pass Symbian Signed canrun without the 'application source untrusted'warning and are published in a business tobusiness applications catalog. ISVs with signedapplications are also able to use the 'forSymbian OS' logo:

    For more information visit www.symbiansigned.com

  • 8/14/2019 Performance Tips for Symbian Applications

    3/40

  • 8/14/2019 Performance Tips for Symbian Applications

    4/40

    Performance Tipspart of the Essential Symbian OS series

    2nd edition, 06/07Published by:Symbian Software Limited2-6 Boundary RowSouthwark

    London SE1 8HPUK

    www.symbian.com

    Trademarks, copyright, disclaimerSymbian, Symbian OS and other associated Symbian marks are alltrademarks of Symbian Software Ltd. Symbian acknowledges the trademarkrights of all third parties referred to in this material. Copyright SymbianSoftware Ltd 2007. All rights reserved. No part of this material may bereproduced without the express written permission of Symbian Software Ltd.

    Symbian Software Ltd makes no warranty or guarantee about the suitabilityor accuracy of the information contained in this document. The informationcontained in this document is for general information purposes only andshould not be used or relied upon for any other purpose whatsoever.

    Compiled by:Andrew Langstaff

    Managing Editor:Satu McNabb

    Design Consultant:Annabel Cooke

    Reviewed by:Mark ShackmanMel PullenAlon Or-BachKrzysztof BliszczakChris Redpath

  • 8/14/2019 Performance Tips for Symbian Applications

    5/40

  • 8/14/2019 Performance Tips for Symbian Applications

    6/40

    What is performancePerformance is a number of measurable characteristics

    that a device can display, be it boot time, ROM size,

    RAM usage, viewing a picture or battery life. The usage

    and features of a device can often dictate desirable

    values for these characteristics. In order to satisfy thesethe software has to be designed and implemented

    accordingly.

    Why it matters

    Often when performance is important, the standardsolution is to increase CPU speed, or dedicate large

    amounts of RAM to caching solutions. Neither of these

    options is really open to mobile phone manufacturers, as

    devices have to be built with battery and cost limitations

    in mind.

    Performance killers

    Most of the performance problems seen on

    smartphones fall into one or other of a small set of

    problems. It is this subset that we will explore in this

    booklet.

  • 8/14/2019 Performance Tips for Symbian Applications

    7/40

    Too much code, not enough data

    Very often during development, an application has someparameters that affect its behavior. These are often stored

    in a file which is processed during startup.

    The problem arises when this configuration becomes

    static, either through a finalization of requirements or

    settling on a set of default values. At this point theparameters could be hard-coded, but often that can mean

    refactoring an application:

    void SomeCode(void)

    {

    // Open file

    // New ReadStream

    // Read some data members into a struct

    // Close file, etc.

    }

    It can also occur when a data structure is created on theheap, which could have been generated at build-time:

    void ConstructL(void)

    {

    TFuncTable *fns = new (ELeave) TFuncTable;fns->iFunc1 = ExampleFunc1;

    fns->iFunc2 = ExampleFunc2;fns->iFunc3 = ExampleFunc3;

    iFuncTable = fns;

    }

    2

  • 8/14/2019 Performance Tips for Symbian Applications

    8/40

    In this example it would be better to have a const copyof the initialized TFuncTable, and either have

    iFuncTable point to it, or, better still, use the constversion in place ofiFuncTable.

    This manifestation of the problem can often be hidden,

    having the function table take the form of an interface

    class.

    In some cases it can be difficult to express the intentionsin easy-to-understand C++ terms: a data structure that is

    read from a file could contain sub-structures. These can

    often become difficult to present as easily-read const

    struct or const class declarations.

    A developer may even choose to have a generated codesolution that takes a human-readable data file and

    converts it into C++ code ready for the compiler.

    Repeated code within loops

    Redundant calculations very often occur in tandem with

    the construction of a complex type.

    Consider the following example:

    ExampleClass::SimpleOperation(SimpleType a,

    SimpleType b)

    {

    //creation of a complex type this is

    //unnecessary, see text

    3

  • 8/14/2019 Performance Tips for Symbian Applications

    9/40

  • 8/14/2019 Performance Tips for Symbian Applications

    10/40

    5

    ExampleClass::SimpleOperation(SimpleType a,ComplexType &b)

    {

    // some code

    }

    ExampleClass::DoSomeComplexComputation(...){

    SimpleType a;

    ComplexType b; //create b as a complex type

    //from outset

    while(moreToDo)

    {

    //pass b as a ComplexType instead of a

    //SimpleType

    SimpleOperation(a, b);

    //some code

    }

    }

    To summarize, care has to be taken to ensure repeated

    calculations or processing does not get done in heavily

    used loops.

  • 8/14/2019 Performance Tips for Symbian Applications

    11/40

    Inefficient heap usage

    Often on embedded systems, the heap has to be used in

    place of the stack. Without care, this can lead to

    excessive heap calls, as stack space is usually used for

    temporary variables.

    void LoopWithHeap(void){

    while(moreToDo)

    {

    CData *temp = new CData;

    GetData(temp);

    ProcessData(temp);

    delete temp;

    }

    }

    Where possible, any temporary variables should be

    reused:

    void LoopWithHeap(void)

    {

    CData *temp = new CData;

    while(moreToDo)

    {

    GetData(temp);

    ProcessData(temp);

    6

  • 8/14/2019 Performance Tips for Symbian Applications

    12/40

    7

    temp->Reset();

    }delete temp;

    }

    Another cause of this problem is the use of segmented

    data structures with granularity that is too fine for the

    amount of data being processed.

    Another possible cause of poor heap usage can be over-

    reliance on realloc. Poorly thought-out design can

    mean that heap cells are required to increase in size,

    and this usually involves an alloc, free and memcpy

    call.

    Limited understanding of library

    API documentation rarely includes any in-depth

    implementation notes. Coding to an inappropriate/poorly

    understood API can lead to problems such as duplicatedor unnecessary processing and data transformation.

    Consider a class that provides access to an array and

    implements bounds checking on the SetElement

    method:

    void ArrayClass::SetSize(int aSize)

    {

  • 8/14/2019 Performance Tips for Symbian Applications

    13/40

    8

    iMaxLength = aSize;

    }

    void ArrayClass::SetElement(int aPos,

    unsigned char aChar)

    {

    if(aPos >= 0 && aPos < iMaxLength)

    {iRawArray[aPos] = aChar;

    }

    }

    Now consider a program written to use this class - it

    needs to add a number of elements to the array:

    void ExampleClass::FillArray()

    {

    //some code

    myArray.SetSize(bytesToProcess);

    for(currentPos = 0; currentPos > operator, a small section of theInternalizeL function that is called is shown below:

    aStream>>card;

    const TInt count(card);

    TRgb rgb;

    for (TInt ii=0;ii>rgb;

    iEikColors->AppendL(rgb);

    }

    We can see that it calls further overloaded >> operatorfunctions for each embedded class. Following throughthe function calls shows that the structures thesefunctions create in memory are built in 32-bit blocks,with each block causing a new read from the file. Even ifthe File Server has a read-ahead cache for the file, thedepth of function calls for each read will cause a

    performance problem.Consider something like the following example instead:

    aStream>>card;

    const TInt count(card);

    aStream->ReadL(iEikColors, count *

    sizeof(TRgb));

    This will be faster, the trade-off is that care has to be taken

    to ensure the internal format ofTRgb hasnt changed.

    13

  • 8/14/2019 Performance Tips for Symbian Applications

    19/40

    Inefficient Database Usage

    Closely coupled to bad file usage is the problem of

    inefficient usage of the Symbian OS database systems.

    Both of the database systems that Symbian OS supports

    make heavy usage of the underlying file system and

    therefore using the APIs provided at this level can lead

    to problems showing up in the file usage patterns.

    The first point to note is in the usage of the Compact()

    API. For durability reasons the database sub-systems do

    not edit in place, that is to say, if you change the

    database structure in any way, the new parts of the

    structure are appended to the end of the database fileand the various markers in the structure are set to point

    to these new areas. This clearly has an impact on file

    size, as a database that is constantly being updated will

    continue to grow in size, unchecked. It is for this reason

    that there is a Compact() API. This essentially rebuilds

    the database, removing the dead areas as it progresses.Clearly then, this operation will be slow, especially for

    large and complex databases, so it is important to

    ensure it is only called when necessary.

    Another important performance consideration when

    working with databases is the schema of the databaseitself. The database components make extensive use of

    caching, to limit the impact of file system usage. Better

    14

  • 8/14/2019 Performance Tips for Symbian Applications

    20/40

    performance can be achieved if the schema used lends

    itself to caching by increasing the locality of often readitems.

    Consider a database that has a single table of records,

    each record having a few small fields and a large field.

    For a particular use case, it is the small fields that are

    accessed more frequently. The performance of the usecase can be improved if the database is restructured so

    that it has two co-indexed tables; one containing just

    the frequently accessed fields, and the other containing

    the larger, infrequently accessed fields.

    If the performance of your database application iscritical, you may wish to measure the performance of

    alternative implementations. As already mentioned,

    database application performance is largely governed by

    the choice of schema and access algorithms so

    additional effort spent working out the best solution for

    you can pay large dividends. If you do decide to producea performance test harness, note that database

    operations have some natural variation in execution time

    so a number of iterations of each measured event will

    be required in order to obtain a true picture.

    15

  • 8/14/2019 Performance Tips for Symbian Applications

    21/40

    Bad use of Design Patterns

    Design Patterns are a useful way of categorizing software

    problems into well-known classes. Common, tried and

    tested solutions to those problems can then be easily

    implemented. However, the use of Design Patterns

    should never be a substitute to actually thinking through

    a problem and deriving a design solution.

    Further problems can arise even once a particular designpattern has been chosen. Design Patterns usually implyan implementation that is described in full ObjectOriented terms. Such OO abstraction is not alwaysappropriate. Blindly implementing the prescribed solution

    can often incur a cost to performance, or an increase incode complexity.

    Consider the following code: the design has suggestedthe use of the State Pattern. One way to implement thispattern is to derive from a common base class, a class

    for each state. In order to initialize the statemachine, the implementers have decided to use aFactory Pattern:

    CExampleStateFactory*

    CExampleStateFactory::NewL()

    {

    CExampleStateFactory* factory= new (ELeave)CExampleStateFactory();

    CleanupStack::PushL(factory);

    16

  • 8/14/2019 Performance Tips for Symbian Applications

    22/40

    // Create all the new states

    factory->iStates[EError] = new (ELeave)

    TExampleStateError(*factory);

    factory->iStates[EStarted] = new (ELeave)

    TExampleStateStarted(*factory);

    factory->iStates[EStopped] = new (ELeave)

    TExampleStateStopped(*factory);

    // etc...

    CleanupStack::Pop();return factory;

    }

    The state factory then owns each of the state classes,and they each take a pointer to the factory. However, if

    we look more closely at the state classes;

    class TExampleStateBase

    {

    public:

    TExampleStateBase(CExampleStateFactory

    *aFactory);

    Inline TExampleStateBase

    *GetState(TStateEnum aState) {return

    iFactory->GetState(aState);}

    private:

    CExampleStateFactory *iFactory;

    }

    17

  • 8/14/2019 Performance Tips for Symbian Applications

    23/40

    TExampleStateBase::TExampleStateBase(CExampleS

    tateFactory *aFactory) : iFactory(aFactory){

    }

    TExampleStateStarted::TExampleStateStarted(CEx

    ampleStateFactory *aFactory) :

    TExampleStateBase(aFactory){

    }

    We can see that the factory pointer that each state takes

    is only used for state switching; this means that the way

    the State Pattern has been implemented has added agreat deal of complexity to the code. This can lead to

    performance problems if the factory is called repeatedly,

    or it can mean that much of the code only exists for

    initialization, which leads to an increase in ROM usage.

    If the State Pattern had been implemented differently,with the state switching handled outside of the State

    Machine itself, then the complex construction could be

    avoided, and much of the Factory Pattern code could be

    handled by compiler intrinsics.

    18

  • 8/14/2019 Performance Tips for Symbian Applications

    24/40

    If each state is simple and contains no member data,

    then the state machine can be encapsulated entirely bythe Virtual Function Pointer Table. In this case we can

    eliminate the need for the Factory Pattern completely,

    and simply change state by using casting, though this

    comes with the trade-off of a decrease in code legibility,

    and the higher risk of defects.

    Generic and future proofed code

    This category of problems comes from an over-reliance

    on frameworks and plugins. It can also involve cases of

    trading ease-of-development for software performance.

    Consider an application that stores some configuration

    parameters in a .ini file. During development it may be

    that these parameters are being altered often, and so it

    makes sense for them to be in an easily edited form.

    However, once they become static, the overhead ofloading and parsing the file can become a performance

    problem.

    The Framework and Plugins approach is one of the

    cornerstones of Symbian OS design, but all too often it

    can be used inappropriately.

    The use of a framework carries with it an overhead in

    terms of code size, as you have to have administrative

    19

  • 8/14/2019 Performance Tips for Symbian Applications

    25/40

    code to scan for plugins, check for changes in plugin

    availability, loading and linking of the plugin DLLs, andcode for selecting a particular plugin. It also carries with

    it an overhead in terms of performance, as the

    framework usually provides a common client interface,

    which internally forwards requests to the plugin in use.

    These are all acceptable tradeoffs when dynamic and in-the-field flexibility is required. However, when the set of

    plugins discovered and used becomes essentially static

    for the lifetime of a piece of software, these costs can

    become unacceptable.

    Future proofing code can also be good practice, butagain if the techniques are wrongly or inappropriately

    applied, there is a cost in code size and performance.

    20

  • 8/14/2019 Performance Tips for Symbian Applications

    26/40

    21

    Developing and testing on the

    emulatorThe Symbian OS emulator is provided as a development

    tool, as it allows a quick turnaround from writing code

    to getting it running. It also allows code to be debugged

    whilst it is running, without expensive hardware tools.

    These facilities are invaluable, however, it is all too easy

    to forget about real hardware testing, especially when

    pressures of release deadlines loom. Hardware testing

    can often end up only being done for proving

    functionality, or ensuring the code runs on hardware

    prior to a release. This can lead to a poor understandingof how code behaves on actual devices, and while this

    doesnt lead directly to performance problems, it can

    often mean they arent detected until the final stages of

    development or after the product ships.

    This can appear to customers as though insufficienttesting was performed or inadequate quality control was

    upheld. Additionally, it limits the scope for any

    improvements that can be made, as there will be little

    time or agreement to make big architectural changes.

  • 8/14/2019 Performance Tips for Symbian Applications

    27/40

    22

    You, your compiler and your code

    As important as it is to know the system and the

    language you are programming for, so it is important to

    understand the basics of the compiler you are using.

    Many modern compilers contain a number of

    optimization phases that try to produce code for a set of

    desired qualities, be they small code size, or fastestexecution path. It is important to understand which of

    these are being chosen in order to appreciate how that

    affects the code the compiler produces.

    Its also important not to assume any tricks done by

    one compiler will be done by another.

    Dont work against the compilerKnow your compiler, understand how the code it

    generates relates to the source you write. Dont write

    code that is too prescriptive. This can force the compiler

    to produce code in a certain way, which may not be the

    most efficient code for the particular case.

    Learn a little assemblerAssembler is often thought of as a black art and is

    usually shied away from by most software developers.

    However, to fully understand how code will run on a

    particular platform, a passing understanding of

    assembler is incredibly useful.

  • 8/14/2019 Performance Tips for Symbian Applications

    28/40

    Quick tips

    Aside from the killers mentioned in this booklet thereare a number of smaller things that should be

    remembered when writing code. A lot of these are good

    common sense, and are usually formalized in a Coding

    Standard. A few of them are worth mentioning here.

    Store results of calls used in loopsAvoid function calls in a loops condition statement.

    Prefer instead to store the value returned from a function

    call in a local variable, unless the result changes after

    each iteration.

    Use references or pointers where necessaryPassing parameters by reference is usually a good thing,

    but dont pass references to integer types if they are

    only ever read from.

    Dont unroll loops

    With modern compilers this type of optimization is nolonger necessary, and can even be counter productive.

    The compiler can perform this optimization where

    appropriate.

    Avoid long ifelse chains

    Its better to use a switch statement, as these can be

    implemented more efficiently. If the conditions arent

    constant integers, such as strings, then consider using a

    lookup table before a switch.

    23

  • 8/14/2019 Performance Tips for Symbian Applications

    29/40

    Use the const qualifier appropriatelyBy marking read-only variables as const the compiler

    can generate more efficient code.

    Quick profiling using the Fast CounterThe user library provides access to a system clock that

    typical has a high resolution, User::FastCounter().

    This can be used to measure the time taken for a

    particular piece of code to execute. The exact nature ofthe counter is device specific, but its attributes can be

    discovered using the HAL:Get() API:

    EFastCounterFrequency returns the frequency of the

    counter, and EFastCounterCountsUp returns an

    indication of which direction the counter progresses in.

    Tools: the Sampling Profiler

    This section is aimed at developers who have access to

    licensee prototypes and certain levels of SDK or are

    using reference boards.

    The Sampling Profiler can be used to provide a rough,

    statistical view of software activity on a device. It does

    this by logging the thread ID and current Program

    Counter value at one millisecond intervals. It is

    accompanied by a command line-based program that can

    be used to analyse this data on a PC. This information

    can then be used to investigate performance problems,

    and inform code inspection of likely bottlenecks.

    24

  • 8/14/2019 Performance Tips for Symbian Applications

    30/40

    Build the ROMTo use the profiler, it first has to be added to the ROM.

    This can be done by adding profiler.iby to thebuildrom command line;

    buildrom h4hrp techview profiler.iby

    Start the profilerThe simplest way to control the profiler is from eshell. A

    command line such as:start profiler start

    This starts another thread that the profiler application

    runs in so you can switch back to other tasks using the

    key combination.

    Run the code you wish to profileAt this point the profiler will be running, and gathering

    samples. A short pause before starting the code to be

    analyzed can help the thread activity analysis phase by

    visually separating out the various chunks of processing

    shown.

    Stop the profilerAfter you have profiled what you need, switch back to

    the eshell and stop the profiler;

    profiler stop

    And then to close the profiler data file;

    profiler unload

    25

  • 8/14/2019 Performance Tips for Symbian Applications

    31/40

    Retrieve the profile dataYou should have a file, profiler.dat, in the root of the C

    drive of the reference board. You can copy it to the MMCcard and transfer it back to the build machine for

    analysis.

    Analyze the data by activityYou should convert the data to a form suitable to be

    displayed in Excel in order to generate a graph, so youget an overall picture of the activity of the software you

    have profiled.

    Copy the profile fileCopy it to the ROM folder as you need the symbol table

    to extract the names. Create the activity format file byrunning the following command:

    analyse r h4hrp_001.techview.symbol

    profiler.dat -v mx > profile.xls

    Create the activity graph

    Open profile.xls file in Excel. To ensure the graph showsthe thread names, delete the first six rows of the data.

    This is summary data and will mess up the graph if it is

    included. Similarly, the time stamps in the first column

    will mess up the graph but you cannot delete them as

    they are needed to cross reference the areas of the

    graph that you are interested in to the actual times.

    26

  • 8/14/2019 Performance Tips for Symbian Applications

    32/40

    Select all of the data and then click on the chart

    wizard. This opens up a four-stage wizard:

    select Area from chart type and Stacked from thesub-type, select Next

    adjust the area to miss out the time stamp in the

    first column. Change theAto a B. E.g.,

    =profile!$A$2:$V$941 gets changed to

    =profile!$B$2:$V$941, select Next

    ignore the next pane and press Next, select As newsheet and press Finish.

    Select the active section and threadsBy looking at the graph created, you should be able to

    work out what your program was doing and when,

    allowing you to locate the area you are interested in.You can hover over the data area with your mouse and a

    pop-up window will tell you which thread was running at

    that point. You can then use the row number of the

    point to find its timestamp by looking at the value in the

    first column of the same row number in the data sheet.

    Additionally, you can delete rows you are not interestedin. Remember that Excel will renumber the rows so

    delete the end of the range first. The graph will be

    redrawn with the new data.

    Create a listing by function

    Once you know the range of timestamps and within

    which thread they occurred, you can create a list of the

    functions ranked in order of the activity.

    For example, if you were interested in what functions

    were called between the 51300 and 76900 timestamps in

    27

  • 8/14/2019 Performance Tips for Symbian Applications

    33/40

  • 8/14/2019 Performance Tips for Symbian Applications

    34/40

    Developer Resources

    Symbian Developer Networkhttp://developer.symbian.com

    Symbian Developer Network newsletterhttp://developer.symbian.com/main/getstarted

    Symbian OS Tools Providershttp://developer.symbian.com/main/tools

    Sony Ericsson Developer Worldhttp://developer.sonyericsson.com

    Forum Nokiahttp://forum.nokia.com

    Sun Microsystems Developer Serviceshttp://developer.java.sun.com

    29

  • 8/14/2019 Performance Tips for Symbian Applications

    35/40

    New from

    ...conducts a rapid tour of the

    architecture of Symbian OS andprovides an introduction to the keyideas of object orientation (OO) insoftware, with a detailed exploration ofthe architecture of Symbian OS.

    This book will help you to become an

    effective Symbian OS developer, andwill give you a deep understanding ofthe fundamental principles uponwhich Symbian OS is based.

    The Symbian OS Architecture Sourcebook

    Symbian OS C++ for Mobile Phones, volume 3

    Symbian Press: developer.symbian.com/main/academy/press

  • 8/14/2019 Performance Tips for Symbian Applications

    36/40

    New from

    is the official guide to passing the ASD

    exam and becoming an AccreditedSymbian Developer. This book isauthored by industry specialists and hasclear and concise explanations.

    Fully up to date for Symbian OS v9

    and S60 3rd Edition, S60Programming is an essentialfoundation to developing software forSymbian OS. This practical book isbased on the authors experiences indeveloping and teaching an academic

    course on Symbian softwaredevelopment.

    Accredited Symbian Developer Primer

    S60 Programming

    Symbian Press: developer.symbian.com/main/academy/press

  • 8/14/2019 Performance Tips for Symbian Applications

    37/40

    Also from

    For all Symbian C++ developers:

    Developing Software for Symbian OSby Steve Babin

    Symbian OS C++ for Mobile Phones Volume 1by Richard Harrison

    Symbian OS C++ for Mobile Phones Volume 2by Richard Harrison

    Symbian OS Explainedby Jo Stichbury

    Symbian OS Internalsby Jane Sales

    Symbian OS Platform Securityby Craig Heath

    Smartphone Operating System Concepts with Symbian OSby Mike Jipping

  • 8/14/2019 Performance Tips for Symbian Applications

    38/40

    Also from

    For enterprise and IT professionals:

    Rapid Mobile Enterprise Development for Symbian OSby Ewan Spence

    For Symbian OS project managers:

    Symbian for Software Leaders

    by David Wood

    For connectivity application developers:

    Programming PC Connectivity Applications for Symbian OSby Ian McDowall

    For Java developers:

    Programming Java 2 Micro Edition for Symbian OSby Martin de Jode

  • 8/14/2019 Performance Tips for Symbian Applications

    39/40

    Published Booklets

    Coding tips

    Signing tips

    Performance TipsEssential UIQ - Getting Started

    Getting started

    Java ME on Symbian OS

    P.I.P.S

    Carbide.c ++

    Data Sharing tips

    Translated Booklets

    Getting Started, Chinese

    Coding Tips, Chinese, Japanese, Korean

    Essential UIQ - Getting Started, ChinesePerformance Tips, Chinese, Japanese

    P.I.P.S, Japanese

    Data Sharing Tips, Japanese

    Also from

  • 8/14/2019 Performance Tips for Symbian Applications

    40/40

    Performance Tips