2011-10-26 12 views
10

Po pewnym przeszukaniu w naszym znajomym google, nie mogłem uzyskać jasnego widoku na następujący punkt.Uzyskuje dostęp do klasy członków C++ poprzez "ten-> członek" szybciej/wolniej niż niejawne wywołanie do "członka"

Jestem przyzwyczajony do wywoływania uczniów z klasy this->. Nawet jeśli nie jest to potrzebne, uważam, że jest to bardziej wyraźne, ponieważ pomaga w utrzymaniu jakiegoś ciężkiego algorytmu z mnóstwem zmiennych.

Podczas pracy nad algorytmem, który powinien być zoptymalizowany, zastanawiałem się, czy użycie this-> zmieni wydajność środowiska wykonawczego, czy nie.

Czy to?

+6

Wystarczy podpowiedź: można sprawdzić wygenerowany zespół, aby to zobaczyć;) – m0skit0

Odpowiedz

14

Nie, połączenie jest identyczne w obu przypadkach.

10

Nie ma to znaczenia. Oto demonstracja z GCC. Źródło jest proste, ale ograniczyłem ten post do różnicy dla jasności.

% diff -s with-this.cpp without-this.cpp 
7c7 
<   this->x = 5; 
--- 
>   x = 5; 

% g++ -c with-this.cpp without-this.cpp 

% diff -s with-this.o without-this.o 
Files with-this.o and without-this.o are identical 
+1

Wykonałem ten sam test za pomocą g ++. :) Działa to samo. Wszystko identyczne. – moustik

+0

@moustik: Oto twoja odpowiedź :-) – Johnsyweb

4

Odpowiedź została udzielona przez zennehoy i oto kod montaż (generowane przez Microsoft kompilator C++) za pomocą prostego klasy testowej:

class C 
{ 
    int n; 
public: 
    void boo(){n = 1;} 
    void goo(){this->n = 2;} 
}; 

int main() 
{ 
    C c; 
    c.boo(); 
    c.goo(); 

     return 0; 
} 

Demontaż Okno w Visual Studio pokazuje, że kod montaż jest taka sama dla obie funkcje:

class C 
{ 
    int n; 
public: 
    void boo(){n = 1;} 
001B2F80 55     push  ebp 
001B2F81 8B EC    mov   ebp,esp 
001B2F83 81 EC CC 00 00 00 sub   esp,0CCh 
001B2F89 53     push  ebx 
001B2F8A 56     push  esi 
001B2F8B 57     push  edi 
001B2F8C 51     push  ecx 
001B2F8D 8D BD 34 FF FF FF lea   edi,[ebp-0CCh] 
001B2F93 B9 33 00 00 00  mov   ecx,33h 
001B2F98 B8 CC CC CC CC  mov   eax,0CCCCCCCCh 
001B2F9D F3 AB    rep stos dword ptr es:[edi] 
001B2F9F 59     pop   ecx 
001B2FA0 89 4D F8    mov   dword ptr [ebp-8],ecx 
001B2FA3 8B 45 F8    mov   eax,dword ptr [this] 
001B2FA6 C7 00 01 00 00 00 mov   dword ptr [eax],1 
001B2FAC 5F     pop   edi 
001B2FAD 5E     pop   esi 
001B2FAE 5B     pop   ebx 
001B2FAF 8B E5    mov   esp,ebp 
001B2FB1 5D     pop   ebp 
001B2FB2 C3     ret 
... 
--- ..\main.cpp ----------------------------- 
void goo(){this->n = 2;} 
001B2FC0 55     push  ebp 
001B2FC1 8B EC    mov   ebp,esp 
001B2FC3 81 EC CC 00 00 00 sub   esp,0CCh 
001B2FC9 53     push  ebx 
001B2FCA 56     push  esi 
001B2FCB 57     push  edi 
001B2FCC 51     push  ecx 
001B2FCD 8D BD 34 FF FF FF lea   edi,[ebp-0CCh] 
001B2FD3 B9 33 00 00 00  mov   ecx,33h 
001B2FD8 B8 CC CC CC CC  mov   eax,0CCCCCCCCh 
001B2FDD F3 AB    rep stos dword ptr es:[edi] 
001B2FDF 59     pop   ecx 
001B2FE0 89 4D F8    mov   dword ptr [ebp-8],ecx 
001B2FE3 8B 45 F8    mov   eax,dword ptr [this] 
001B2FE6 C7 00 02 00 00 00 mov   dword ptr [eax],2 
001B2FEC 5F     pop   edi 
001B2FED 5E     pop   esi 
001B2FEE 5B     pop   ebx 
001B2FEF 8B E5    mov   esp,ebp 
001B2FF1 5D     pop   ebp 
001B2FF2 C3     ret 

a kod w głównym:

C c; 
    c.boo(); 
    001B2F0E 8D 4D F8    lea   ecx,[c] 
    001B2F11 E8 00 E4 FF FF  call  C::boo (1B1316h) 
    c.goo(); 
    001B2F16 8D 4D F8    lea   ecx,[c] 
    001B2F19 E8 29 E5 FF FF  call  C::goo (1B1447h) 

Kompilator Microsoft domyślnie używa wywołania __thiscall dla wywołań członków klasy i this wskaźnik jest przekazywany przez rejestr ECX.

1

W kompilacji języka uczestniczy kilka warstw.

Różnica między dostępem do member jako member, this->member, MyClass::member itd ... jest różnicą składniową.

Dokładniej, jest to kwestia wyszukiwania nazw i tego, w jaki sposób front-end kompilatora "znajdzie" dokładnie ten element, do którego się odnosisz. Dlatego możesz przyspieszyć kompilację, ponieważ jest bardziej precyzyjny ... choć będzie niezauważalny (jest dużo więcej czasochłonnych zadań związanych z C++, takich jak otwieranie wszystkich tych elementów).

Ponieważ (w tym przypadku) odnoszą się do tego samego elementu, to powinno być nie ma znaczenia.


Teraz można wykonać interesującą paralelę z językami interpretowanymi. W języku interpretowanym wyszukiwanie nazwy będzie opóźnione do momentu wywołania linii (lub funkcji). W związku z tym może mieć wpływ na środowisko uruchomieniowe (choć po raz kolejny prawdopodobnie nie jest tak naprawdę zauważalne).

Powiązane problemy