2013-12-02 2 views
0

Есть ли разница в вычислительной стоимостили пустой «еще» стоимость в любое время

if(something){ 
    return something; 
}else{ 
    return somethingElse; 
} 

и

if(something){ 
    return something; 
} 
//else (put in comments for readibility purposes) 
return somethingElse; 

В теории мы имеем команду (еще), но это не кажется, это должно сделать разницу в действии.

Редактировать: После запуска кода для разных размеров набора, я обнаружил, что на самом деле существует различие, код без остатка примерно на 1,5% эффективнее. Но это, скорее всего, зависит от компилятора, о чем свидетельствуют многие люди ниже. Код я тестировал на:

int withoutElse(bool a){ 
if(a) 
    return 0; 
return 1; 

} 


int withElse(bool a){ 
if(a) 
    return 0; 
else 
    return 1; 
} 


int main(){ 
using namespace std; 
bool a=true; 
clock_t begin,end; 
begin= clock(); 
for(__int64 i=0;i<1000000000;i++){ 
    a=!a; 
    withElse(a); 
} 
end = clock(); 
cout<<end-begin<<endl; 

begin= clock(); 
for(__int64 i=0;i<1000000000;i++){ 
    a=!a; 
    withoutElse(a); 
} 
end = clock(); 
cout<<end-begin<<endl; 

return 0; 
} 

Проверено на петлях от 1 000 000 до 1 000 000 000, и результаты были последовательно разные

Edit 2: код Ассамблеи (еще раз, генерируется с помощью Visual Studio 2010) также показывает небольшую разницу (appareantly, я не гожусь с сборщиков :()

[email protected]@[email protected] PROC     ; withElse, COMDAT 
    ; Line 12 
push ebp 
mov ebp, esp 
sub esp, 192    ; 000000c0H 
push ebx 
push esi 
push edi 
lea edi, DWORD PTR [ebp-192] 
mov ecx, 48     ; 00000030H 
mov eax, -858993460    ; ccccccccH 
rep stosd 
    ; Line 13 
movzx eax, BYTE PTR _a$[ebp] 
test eax, eax 
je SHORT [email protected] 
    ; Line 14 
xor eax, eax 
jmp SHORT [email protected] 
    ; Line 15 
jmp SHORT [email protected] 
    [email protected]: 
    ; Line 16 
mov eax, 1 
    [email protected]: 
    ; Line 17 
pop edi 
pop esi 
pop ebx 
mov esp, ebp 
pop ebp 
ret 0 
    [email protected]@[email protected] ENDP     ; withElse 

и

[email protected]@[email protected] PROC    ; withoutElse, COMDAT 
    ; Line 4 
push ebp 
mov ebp, esp 
sub esp, 192    ; 000000c0H 
push ebx 
push esi 
push edi 
lea edi, DWORD PTR [ebp-192] 
mov ecx, 48     ; 00000030H 
mov eax, -858993460    ; ccccccccH 
rep stosd 
    ; Line 5 
movzx eax, BYTE PTR _a$[ebp] 
test eax, eax 
je SHORT [email protected] 
    ; Line 6 
xor eax, eax 
jmp SHORT [email protected] 
    [email protected]: 
    ; Line 7 
mov eax, 1 
    [email protected]: 
    ; Line 9 
pop edi 
pop esi 
pop ebx 
mov esp, ebp 
pop ebp 
ret 0 
    [email protected]@[email protected] ENDP    ; withoutElse 
+6

Преждевременная оптимизация - это корень всего зла. – devnull

+2

Проверьте сгенерированный код ассемблера для обоих вариантов. Это единственный способ быть уверенным. –

+0

не совсем вопрос теории сложности. – RichardPlunkett

ответ

4

Это в целом отличается, но компилятор может решить выполнить тот же скачок в обоих случаях (он будет всегда делать это всегда). Лучший способ увидеть, что делает компилятор, - это прочитать ассемблер. Предполагая, что вы используете GCC, вы можете попробовать с

gcc -g -c -fverbose-asm myfile.c; objdump -d -M intel -S myfile.o > myfile.s 

, который создает сочетание ассемблера/с кодом и делает работу легче в самом начале.

Что касается вашего примера:

case1

if(something){ 
23: 83 7d fc 00    cmp DWORD PTR [ebp-0x4],0x0 
27: 74 05     je  2e <main+0x19> 
    return something; 
29: 8b 45 fc    mov eax,DWORD PTR [ebp-0x4] 
2c: eb 05     jmp 33 <main+0x1e> 
}else{ 
    return 0; 
2e: b8 00 00 00 00   mov eax,0x0 
} 

Вариант 2

if(something){ 
23: 83 7d fc 00    cmp DWORD PTR [ebp-0x4],0x0 
27: 74 05     je  2e <main+0x19> 
    return something; 
29: 8b 45 fc    mov eax,DWORD PTR [ebp-0x4] 
2c: eb 05     jmp 33 <main+0x1e> 
return 0; 
2e: b8 00 00 00 00   mov eax,0x0 

Как вы можете себе представить, не существует никаких различий!

+0

Что делать, если есть еще код после if else? – brunch875

+1

Давайте еще раз подчеркнем, что это код, который генерирует один конкретный компилятор в сборке отладки без оптимизации. Вы можете получить значительно разные результаты для других компиляторов или параметров компилятора. Однако нижняя линия все же применяется: разница вряд ли будет достаточно большой, чтобы быть любой проблемой. – ComicSansMS

+0

Ваш ответ был наиболее полезным, но, как я отмечаю в своем редактировании, в MVS на самом деле есть небольшая разница – Xyzk

2

Это не будет компилироваться, если вы наберете `вернуть Думает, что после того, как код компилируется, все сослагательное наклонение, ELSES и петли изменяются на

If (cond) { code A } code B 

Гото превращается в

if cond is false jump to code b 
code A 
code B 

и Если (условие) {код А} еще {B}, код код с

превращается в

if cond is false jump to code B 
code A 
ALWAYS jump to code C 
code B 

code C 

Большинство процессоров «догадываются», будут ли они прыгать или нет, прежде чем проверять, действительно ли они прыгают. В зависимости от процессора это может повлиять на производительность, чтобы не догадаться.

Так что ответ ДА! (если в конце первого сравнения не будет ВСЕГДА прыгать). Выполнение прыжка ALLWAYS, который не находится в первом случае, займет 2-3 цикла.

+0

Хорошее место на этом –

+0

Но это вопрос, добавляет ли он еще один goto, аналогично if-else (condition), или компилятор действительно относится к нему как к случаю speciall. – Xyzk

Смежные вопросы