Różnica między konstrukcją if/else i operatorem potrójnym ?:

0

Cześć,

zastanawia mnie porównanie wydajności między zwykłym warunkiem a operatorem potrójnym w języku C.

Zobaczmy przykłady, które porównam wykorzystując stronę godbolt.org:

int square_ifelse(int num) {
    if (num > 5)
        num++;
    else
        num--;
    return(num);
}
int square_ternary(int num) {
    num > 5 ? num++ : num--;
    return(num);
}

Kod assemblerowy dla x86-64 gcc 8.1 wychodzi odpowiednio:

square_ifelse:
  push rbp
  mov rbp, rsp
  mov DWORD PTR [rbp-4], edi
  cmp DWORD PTR [rbp-4], 5
  jle .L2
  add DWORD PTR [rbp-4], 1
  jmp .L3
.L2:
  sub DWORD PTR [rbp-4], 1
.L3:
  mov eax, DWORD PTR [rbp-4]
  pop rbp
  ret
square_ternary:
  push rbp
  mov rbp, rsp
  mov DWORD PTR [rbp-4], edi
  cmp DWORD PTR [rbp-4], 5
  jle .L2
  mov eax, DWORD PTR [rbp-4]
  add eax, 1
  mov DWORD PTR [rbp-4], eax
  jmp .L3
.L2:
  mov eax, DWORD PTR [rbp-4]
  sub eax, 1
  mov DWORD PTR [rbp-4], eax
.L3:
  mov eax, DWORD PTR [rbp-4]
  pop rbp
  ret

Czy na podstawie różnicy wynoszącej 4 dodatkowe instrukcje mogę sądzić, że nie jest to efektywne wykorzystanie operatora potrójnego w tym przypadku?

Dzięki z góry za odpowiedzi.

1

Najwyraźniej obydwa kody skompilowałeś w innym kontekście / z innymi przełącznikami, ponieważ zwracają identyczny kod:

https://hastebin.com/apodivuxes.css (-O0)
https://hastebin.com/umazoletug.apache (-O3)

1

Nowoczesny kompilator powinien (powinien!) wyoptymalizować to do tej samej/porównywalnej postaci asemblerowej.
Z if/else nie zrobisz za to (bez zmiennych pomocniczych) tego const int foo { bar < 3 ? 1:5 }; Kwestia czytelności co gdzie powinno trafić.

0

@Patryk27: Dzięki za edycję komentarza oraz odpowiedź! Sprawdziłem jeszcze raz (korzystam ze strony https://godbolt.org/) - nie skorzystałem z żadnych dodatkowych przełączników używając jedynie kompilatora gcc 8.1 dla architektury x86-64. Najwyraźniej optymalizacja kompilatora ma tutaj znaczenie i powoduje wyprodukowanie takiego samego kodu asemblerowego.
@alagner: Dzięki za interesujący przykład! Dodam jeszcze różnicę, że tutaj mamy jedynie konstrukcję dla if/else, a dla operatora potrójnego wyrażenie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1