Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changes between Version 1 and Version 2 of code/PerformanceTips


Ignore:
Timestamp:
Apr 10, 2005, 6:51:57 PM (20 years ago)
Author:
simon
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • code/PerformanceTips

    v1 v2  
    22
    33== Inline Functions ==
    4 Function declared as inline will be included in the calling code in compilation time. This speeds up execution because all the branching stuff hasn't to be executed. The speedup will be the bettest, when these functions are only very small, so when the execution of the function needs aproximatly the same time as the branching time. Here a little example:
     4Function declared as inline will be included in the calling code in compilation time. This speeds up execution because all the branching stuff doesn't have to be executed. The speedup is maxed out, when these functions are only very small, so when the execution of the function needs approximatly the same time as the branching time. Here a little example:
    55{{{
    66class Test
     
    2222 * ''void !WorldEntity::tick(float time) {}'' this function is called everytime a frame is rendered
    2323 * ''bool !BaseObject::isFinalized()'' this function is called from the garbage collector every time he does its job
    24 Don't use it for functions that are normaly called before and after the game time. Or functions that are rarely called at all.
    25 
     24Don't use it for functions that are normally called before and after the game time or functions that are rarely called at all.
     25Inlining brings some problems, too. First: Inlined code doesn't have to be made inline by the compiler. Some reasons, why this could happen are: loops in the inlined code, recursive code in the inlined code and function calls in the inlined code.
    2626 
    2727== Memory Allocation and Deletion: new, delete ==
    28 Creation of new Objects needs very much time compared to mathematical operations. It can take you 20 to 200 times the time a normal function call coasts, depending of how much the class has been derived, etc (measured on a pentium II computer). So try to make as few new objects you can and recycle them if possible (altough it can lead to strang code).[br]
    29 Given the case, you have to create a new object, try to make it like this:
     28Creation of new objects needs very much time compared to mathematical operations. It can take from 20 to 200 times the time a normal function call costs depending of how deeply the class has been derived (measured on a pentium II computer). Try to make as few new objects you can and recycle them if possible (altough it can lead to strange code).[br]
     29Given the case, that you have to create a new object, try to make it like this:
    3030{{{
    3131
     
    3838}}}
    3939To free the memory is very important, if the function is called multiple times! [br]
    40 If you write it in the follwing way, you don't have to delete it:
     40If you write it the following way, you don't have to delete it:
    4141{{{
    4242void ExampleClass::goodStyle2()
     
    4646}
    4747}}}
    48 The difference is, that this ''obj'' will be stored as a temporary variable and deleted after the function returns! This leads to some other problems: If you want to give a reference to object via the argument of a function to another object, '''never''' use these temporary variables.
     48The difference is, that this ''obj'' will be stored as a temporary variable and deleted after the function returns! This leads to some other problems: If you want to give a reference to said object via the argument of a function to another object, '''never''' use these temporary variables.
    4949{{{
    5050void SomeClass::wantsObjectReference(Object* reference)
     
    5555void ExampleClass::badBadBad()
    5656{
    57   Object obj;                      /* this is only a local reference! automaticly deleted after function return */
     57  Object obj;                      /* this is only a local reference automatically deleted after function return */
    5858  SomeClass* sc = new SomeClass(); /* creation of a new object needs much time, avoid it if possible - here we need it */
    5959  sc->wantObjectReference(&obj);   /* BAD BAD BAD BAD!!!!! */
     
    6161}
    6262}}}
    63 The compile will complain about such things with a message like this: "WARNING: taking address of a temprary". And Mr.Compiler is absolutly right!
    64 Better would be:
     63The compile will complain about such things with a message like this: "WARNING: taking address of a temporary". And Mr. compiler is absolutly right!
     64A better way would be:
    6565{{{
    6666void SomeClass::wantsObjectReference(Object* reference)
     
    7171void ExampleClass::badBadBad()
    7272{
    73   Object* obj = new Object*();     /* this is only a local reference! automaticly deleted after function return */
     73  Object* obj = new Object*();     /* this is only a local reference! automatically deleted after function return */
    7474  SomeClass* sc = new SomeClass(); /* creation of a new object needs much time, avoid it if possible - here we need it */
    7575  sc->wantObjectReference(obj);    /* BAD BAD BAD BAD!!!!! */
     
    7777}
    7878}}}
     79 
     80== Redundant code ==
     81As anything which can be done fast should be done fast, we can optimise many functions which take and return values. Often code for an operator or something similar will look like that:
     82{{{
     83CVector3f operator+( CVector3f v )
     84{
     85   CVector3f returnVector;
     86   returnVector.m_x = m_x + v.m_x;
     87   returnVector.m_y = m_y + v.m_y;
     88   returnVector.m_z = m_z + v.m_z;
    7989
     90   return returnVector;
     91}
     92}}}
     93Now what's wrong here is the local variable. When the temporary object is made on the first line, the constructor is called and the object initialized. But we didn't want that to happen! We assign new values anyways in the next lines. Always keep in mind the time wasted when creating objects. [br]
     94The copy constructor is called again in the end of the function, as returnVector is a local variable. This just shows why this style is very bad. [br]
     95A problem which lies hidden is the problem of parameter. As the parameter is a copy of the original argument, we get another useless object construction. [br]
     96A better way would be:
     97{{{
     98CVector3f operator+( const CVector3f &v ) const
     99{
     100   return CVector3f( m_x + v.m_x, m_y + v.m_y,  m_z + v.m_z )
     101}
     102}}}
     103This implementation saves us time as 2 less copy constructors are called. In this particular problem we could save time by knowing waht happens behind the scenes.