Для видов оптимизации, которые вы предлагаете, вы должны написать свой код для ясности и не оптимизировать их, пока не получите доказательство того, что они являются узким местом.
Одна из опасностей попыток микрооптимизации, подобных этой, состоит в том, что вы, вероятно, сделаете вещи медленнее , потому что компилятор умнее, чем вы, в большинстве случаев.
Возьми свою "оптимизацию":
const int windowPosX = (screenWidth * 0.5) - (windowWidth * 0.5);
В мире нет серьезного компилятора, который бы не знал, что самый быстрый способ деления на два - это сдвиг вправо на единицу. Умножение на число с плавающей запятой 0,5 на самом деле дороже, поскольку требует преобразования в число с плавающей запятой и обратно и выполнение двух умножений (которые стоят дороже, чем сдвиги).
Но не верьте мне на слово. Посмотрите, что на самом деле делает компилятор. gcc 4.3.3 в 32-битной Ubuntu (-O3, -msse3, -fomit-frame-pointer) компилирует это:
int posx(unsigned int screen_width, unsigned int window_width) {
return (screen_width / 2) - (window_width / 2);
}
к этому:
00000040 <posx>:
40: 8b 44 24 04 mov eax,DWORD PTR [esp+0x4]
44: 8b 54 24 08 mov edx,DWORD PTR [esp+0x8]
48: d1 e8 shr eax,1
4a: d1 ea shr edx,1
4c: 29 d0 sub eax,edx
4e: c3
Две смены (с использованием непосредственного операнда) и вычитание. Очень дешевый. С другой стороны, он компилирует это:
int posx(unsigned int screen_width, unsigned int window_width) {
return (screen_width * 0.5) - (window_width * 0.5);
}
на это:
00000000 <posx>:
0: 83 ec 04 sub esp,0x4
3: 31 d2 xor edx,edx
5: 8b 44 24 08 mov eax,DWORD PTR [esp+0x8]
9: 52 push edx
a: 31 d2 xor edx,edx
c: 50 push eax
d: df 2c 24 fild QWORD PTR [esp]
10: 83 c4 08 add esp,0x8
13: d8 0d 00 00 00 00 fmul DWORD PTR ds:0x0
15: R_386_32 .rodata.cst4
19: 8b 44 24 0c mov eax,DWORD PTR [esp+0xc]
1d: 52 push edx
1e: 50 push eax
1f: df 2c 24 fild QWORD PTR [esp]
22: d8 0d 04 00 00 00 fmul DWORD PTR ds:0x4
24: R_386_32 .rodata.cst4
28: de c1 faddp st(1),st
2a: db 4c 24 08 fisttp DWORD PTR [esp+0x8]
2e: 8b 44 24 08 mov eax,DWORD PTR [esp+0x8]
32: 83 c4 0c add esp,0xc
35: c3 ret
То, что вы видите, это преобразование в число с плавающей запятой, умножение на значение из сегмента данных (который может или не может быть в кеше), и преобразование обратно в целое число.
Пожалуйста, подумайте об этом примере, когда вы испытываете желание выполнить микрооптимизацию, подобную этой. Мало того, что это преждевременно, но это может не помочь вообще (в этом случае это значительно больно!)
Серьезно: не делай этого. Я думаю, что золотое правило никогда не состоит в том, чтобы проводить оптимизацию, подобную этой, если вы регулярно не проверяете выходные данные своего компилятора, как я сделал здесь.