Changes between Version 1 and Version 2 of code/PerformanceTips
- Timestamp:
- Apr 10, 2005, 6:51:57 PM (20 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
code/PerformanceTips
v1 v2 2 2 3 3 == 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:4 Function 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: 5 5 {{{ 6 6 class Test … … 22 22 * ''void !WorldEntity::tick(float time) {}'' this function is called everytime a frame is rendered 23 23 * ''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 normal y called before and after the game time. Or functions that are rarely called at all.25 24 Don't use it for functions that are normally called before and after the game time or functions that are rarely called at all. 25 Inlining 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. 26 26 27 27 == 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 strangcode).[br]29 Given the case, you have to create a new object, try to make it like this:28 Creation 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] 29 Given the case, that you have to create a new object, try to make it like this: 30 30 {{{ 31 31 … … 38 38 }}} 39 39 To 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:40 If you write it the following way, you don't have to delete it: 41 41 {{{ 42 42 void ExampleClass::goodStyle2() … … 46 46 } 47 47 }}} 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.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 said object via the argument of a function to another object, '''never''' use these temporary variables. 49 49 {{{ 50 50 void SomeClass::wantsObjectReference(Object* reference) … … 55 55 void ExampleClass::badBadBad() 56 56 { 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 */ 58 58 SomeClass* sc = new SomeClass(); /* creation of a new object needs much time, avoid it if possible - here we need it */ 59 59 sc->wantObjectReference(&obj); /* BAD BAD BAD BAD!!!!! */ … … 61 61 } 62 62 }}} 63 The compile will complain about such things with a message like this: "WARNING: taking address of a temp rary". And Mr.Compiler is absolutly right!64 Betterwould be:63 The compile will complain about such things with a message like this: "WARNING: taking address of a temporary". And Mr. compiler is absolutly right! 64 A better way would be: 65 65 {{{ 66 66 void SomeClass::wantsObjectReference(Object* reference) … … 71 71 void ExampleClass::badBadBad() 72 72 { 73 Object* obj = new Object*(); /* this is only a local reference! automatic ly deleted after function return */73 Object* obj = new Object*(); /* this is only a local reference! automatically deleted after function return */ 74 74 SomeClass* sc = new SomeClass(); /* creation of a new object needs much time, avoid it if possible - here we need it */ 75 75 sc->wantObjectReference(obj); /* BAD BAD BAD BAD!!!!! */ … … 77 77 } 78 78 }}} 79 80 == Redundant code == 81 As 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 {{{ 83 CVector3f 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; 79 89 90 return returnVector; 91 } 92 }}} 93 Now 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] 94 The 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] 95 A 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] 96 A better way would be: 97 {{{ 98 CVector3f 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 }}} 103 This 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.