| 104 | |
| 105 | == Pointer arithmetic == |
| 106 | Dereferencing a pointer takes some time. If you do something like this: |
| 107 | {{{ |
| 108 | for( int i = 0; i < numPixels; i++ ) |
| 109 | { |
| 110 | rendering_context->back_buffer->surface->bits[i] = some_value; |
| 111 | } |
| 112 | }}} |
| 113 | you're wasting much time in the loop dereferencing.[br] |
| 114 | Instead you could do this: |
| 115 | {{{ |
| 116 | unsigned char *back_surface_bits = rendering_context->back_buffer->surface->bits; |
| 117 | for( int i = 0; i < numPixels; i++ ) |
| 118 | { |
| 119 | back_surface_bits[i] = some_value; |
| 120 | } |
| 121 | }}} |
| 122 | or even faster: |
| 123 | {{{ |
| 124 | unsigned char *back_surface_bits = rendering_context->back_buffer->surface->bits; |
| 125 | for( int i = 0; i < numPixels; i++,back_surface_bits++ ) |
| 126 | { |
| 127 | *back_surface_bits = some_value; |
| 128 | } |
| 129 | }}} |
| 130 | By leaving the brackets and going into pointer arithmetics the addresses don't have to be calculated, saving you some time to drink a cup of coffee. |
| 131 | |
| 132 | == Math optimisations == |
| 133 | Bit shifting is a very fast way to perform integer math. It is limited in it's use, as you can only multiply and divide by 2, but it is very fast. Consider: |
| 134 | {{{ |
| 135 | i *= 256; //i = i * 256 |
| 136 | i = i << 8; //i = i * 256 |
| 137 | }}} |
| 138 | Logically, they are the same. For this simple example, the compiler might even turn the first into the second, but as you get more complex the compiler might not be able to make the conversion. Example: |
| 139 | {{{ |
| 140 | i *= 272 //i = i * 272 |
| 141 | i = i << 8 + i << 4 //i = i * 272 |
| 142 | }}} |
| 143 | One should also keep in mind, that multiplying is way slower than adding. This is why this makes sense: |
| 144 | {{{ |
| 145 | a*b + a*c; |
| 146 | a*(b+c); //This gets rid of one multiplication, with no change to the meaning of the expression |
| 147 | }}} |
| 148 | A variation on the previous item, but this time, replacing two divisions by a division and a multiplication. On every platform that I am aware of, divisions are slower than multiplications, so this rewrite will provide a speed improvement. |
| 149 | {{{ |
| 150 | b/a + c/a = (1/a)*(b+c); |
| 151 | }}} |
| 152 | The last example is perhaps not so obvious, but the C++ standard requires lazy evaluation. |
| 153 | {{{ |
| 154 | (a || b ) && c; |
| 155 | c && ( a || b ); |
| 156 | }}} |
| 157 | In the first case, whenever c happens to be false, ( a || b ) has to be evaluated, whereas in the second case, it can be skipped as the entire expression can never evaluate to true anymore. |