Лаба 3 Профайлер / Варианты по оптимизации
.doc
Некоторые конструкции языка, пригодные для оптимизации
1. |
Допустим есть. const float a = 100.0f; float some1 = some3 * 1.0f / a; float some2 = some4 * 1.0f / a;
более эффективно написать не: const float a_inv = 1.0f / a; some1 = some3 * a_inv; some2 = some4 * a_inv;
а так: some1 = some3 * (1.0f / a); some2 = some4 * (1.0f / a);
|
Операторы с равным приоритетом выполняются последовательно. Это значит, что будет выполнено сначала умножение, а затем деление. Если же обрамить операцию деления в скобки, то ее выполнит компилятор, а в реальном времени будет выполняться только операция умножения. Что качается отличий варианта 3 от варианта 2, то в 3-ем варианте не создается дополнительной переменной, нет нужны глядя на код думать о том, что это за переменная. А эффективность 2-го и 3-го варианты будет одинаковой.
|
2. |
void Func( int* a ) { int b = 10;
Следующие строки одинаковые по эффективности (по времени выполнения): b = 100; *a = 100; }
|
Это происходит по тому, что доступ к стековой переменной осуществляется по указателю на стек. Тоже идет разыменование указателя.
|
3. |
|
Если есть большой массив структур, то нужно делать размер его элементов равным степени двойки. Тогда проход по такому массиву будет значительно быстрее (в 4 -6 раз), за счет выравнивания указателя на каждую структуру в массиве.
|
4. |
float f = 1.0f; *(int*)&f ^= 0x80000000; - быстрее чем f *= -1.0f; |
|
5. |
Можно так: bool b; int a = b ? x : y;
Но быстрее: int b; ( 0 - false, -1 - true) int a = (x & b) | (y & ~b); |
|
6. |
int a, b; 1. int x = (a >= b ? 1 : 0); 2. int x = (a >= b ? -1 : 0);
Можно заменить на: 1. int x = (b - a) >> 31; 2. int x = (b - a) & 0x80000000; |
|
07.10.15 |
i32 iIndex;
Условие: if( iIndex < 0 && iIndex >= iSize ) Можно заменить таким: if( (u32)iIndex >= iSize )
Условие: if( i >= min && i <= max ) Можно заменить таким: if( (u32)(i-min) <= (u32)max - min ) |
|
8. |
void Compute( conat char* name ) { if( !name ) { A a; // переменная будет жить до конца условия, но не до конца функции ... } } |
Минимизировать количество локальных переменных. Тогда компилятор сможет их хранить в регистрах, а не на стеке
|
9. |
|
Не передавайте в функцию большое количество параметров. Большое количество параметров будет хранится на стеке, а не в регистрах. Если нужно передать большую структуру воспользуйтесь указателем (ссылкой), но не передавайте по значению.
|
10. |
SomeClass::SomeClass( int val1, int val2 ) : m_val1( val1 ) , m_val2( val2 ) { }
Вместо: SomeClass::SomeClass( int val1, int val2 ) { m_val1 = val1; m_val2 = val2; }
|
используйте список инициализации конструктора, вместо присвоения значений в его теле. Так поля будут инициализироваться один раз. Это наиболее ощутимо, если эта переменная — класс. Тогда в первом случае вызовется только конструктор, а во втором конструктор и функция.
|
11. |
Вместо: Struct GetData() { Struct st;.... return st; }
Писать так: void GetData( Struct& st ) // ну или по указателю передать { st.value = ...; ... } |
Если нужно чтобы функция вернула структуру размером более 4 байт, то передайте эту структуру в функцию по указателю или ссылке. Пусть функция инициализирует ее поля через указатель.
|
12. |
|
Используйте int вместо char, short для локальных переменных и для переменных структур, если нет цели минимизировать потребление памяти. int будет работать быстрее. При использовании переменных char и short, они будут конвертироваться в int во всех арифметических операциях.
|
13. |
|
Делайте настолько простой конструктор, насколько возможно. Не забывайте, что он будет вызываться при любом создании объекта. Если объект часто создается в промежуточных вычислениях, то лучше,
чтобы конструктор был мал. Например делая структуру Vector3 не нужно в конструкторе по умолчанию инициализировать поля x,y,z нулями. Сделайте для этого лучше отдельный конструктор, а конструктор по умолчанию оставьте пустым.
|
14. |
|
Не создавайте возвращаемого результата в функции, у которой возвращаемое значение никогда не будет использоваться. Компилятор не знает, будет ли оно использоваться и всегда будет возвращать значение. Например не делайте тип bool возвращаемым значением функции, если не собираетесь его обрабатывать
|
15. |
|
Не делайте функции виртуальными без необходимости. Вызов виртуальной функции значительно дороже вызова обычной функции, поэтому не нужно делать ее виртуальной предполагая, что кому-нибудь понадобится изменить ее поведение в будущем. Если такая необходимость возникнет, то можно будет легко сделать функцию виртуальной в будущем.
|