2011-10-26 5 views
10

Dopo aver cercato sul nostro amico google, non ho potuto ottenere una visione chiara sul seguente punto.È l'accesso alla classe membro C++ tramite "questo-> membro" più veloce/più lento della chiamata implicita a "membro"

Sono abituato a chiamare i membri della classe con this->. Anche se non necessario, lo trovo più esplicito in quanto aiuta a mantenere un po 'pesante algoritmo con un sacco di vars.

Mentre sto lavorando su un algoritmo che dovrebbe essere ottimizzato, mi chiedevo se l'utilizzo di this-> avrebbe alterato le prestazioni del runtime o meno.

Lo fa?

+6

Solo un suggerimento: è possibile controllare l'assembly generato per vederlo;) – m0skit0

risposta

14

No, la chiamata è esattamente la stessa in entrambi i casi.

10

Non fa alcuna differenza. Ecco una dimostrazione con GCC. L'origine è semplice, ma ho limitato questo post alla differenza per chiarezza.

% 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

Stavo facendo lo stesso test con g ++. :) Funziona allo stesso modo. Tutto identico. – moustik

+0

@moustik: Ecco la tua risposta, quindi :-) – Johnsyweb

4

risposta è stata data da zennehoy ed ecco codice assembly (generato da Microsoft compilatore C++) per una semplice classe di test:

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

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

     return 0; 
} 

Smontaggio finestra in Visual Studio mostra che il codice di installazione è uguale per funzioni di entrambi:

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 

E il codice nella principale:

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) 

Il compilatore Microsoft utilizza la convenzione di chiamata __thiscall per impostazione predefinita per le chiamate dei membri della classe e il puntatore this viene passato tramite il registro ECX.

1

Ci sono diversi livelli coinvolti nella compilazione di una lingua.

La differenza tra l'accesso ai member come member, this->member, MyClass::member ecc ... è una differenza sintattica.

Più precisamente, è una questione di ricerca del nome e di come il front-end del compilatore "trova" l'elemento esatto a cui ci si riferisce. Pertanto, si potrebbe velocizzare la compilazione essendo più preciso ... anche se sarà impercettibile (ci sono molte più attività che richiedono tempo in C++, come l'apertura di tutte quelle che includono).

Poiché (in questo caso) si fa riferimento allo stesso elemento, è non importa.


Ora, un interessante parallelo può essere fatto con linguaggi interpretati. In una lingua interpretata, la ricerca del nome verrà posticipata al momento in cui viene chiamata la linea (o la funzione). Pertanto, potrebbe avere un impatto in fase di esecuzione (anche se, ancora una volta, probabilmente non molto evidente).

Problemi correlati