2011-10-26 26 views
10

Sau khi tìm kiếm trên google của chúng tôi, tôi không thể xem rõ điểm sau đây.Truy cập vào thành viên C++ thông qua "thành viên này" nhanh hơn/chậm hơn cuộc gọi ngầm đến "thành viên"

Tôi thường gọi cho các thành viên lớp học là this->. Ngay cả khi không cần thiết, tôi thấy nó rõ ràng hơn vì nó giúp khi duy trì một số thuật toán nặng với vô số các vars.

Khi tôi đang làm việc trên một thuật toán được tối ưu hóa, tôi đã tự hỏi liệu việc sử dụng this-> có làm thay đổi hiệu suất thời gian chạy hay không.

Có phải không?

+6

Chỉ cần một gợi ý: bạn có thể kiểm tra lắp ráp được tạo ra để xem điều đó;) – m0skit0

Trả lời

14

Không, cuộc gọi hoàn toàn giống nhau trong cả hai trường hợp.

10

Nó không tạo ra bất kỳ sự khác biệt nào. Đây là một cuộc biểu tình với GCC. Nguồn là lớp đơn giản, nhưng tôi đã hạn chế bài đăng này với sự khác biệt cho sự rõ ràng.

% 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

Tôi đã làm thử nghiệm tương tự với g ++. :) Nó hoạt động tương tự. Tất cả mọi thứ giống hệt nhau. – moustik

+0

@moustik: Có câu trả lời của bạn, sau đó :-) – Johnsyweb

4

trả lời đã được đưa ra bởi zennehoy và đây là mã lắp ráp (tạo ra bởi Microsoft C++) cho một lớp thử nghiệm đơn giản:

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

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

     return 0; 
} 

Disassembly Window trong Visual Studio cho thấy rằng mã lắp ráp là như nhau cho chức năng cả hai:

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 

Và mã kiểm tra vào chính:

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) 

Trình biên dịch Microsoft sử dụng quy ước gọi __thiscall theo mặc định cho các cuộc gọi thành viên của lớp và con trỏ this được chuyển qua thanh ghi ECX.

1

Có một số lớp liên quan đến việc biên soạn ngôn ngữ.

Sự khác biệt giữa việc truy cập membermember, this->member, MyClass::member vv ... là sự khác biệt về cú pháp.

Chính xác hơn, đó là vấn đề tra cứu tên và cách phần đầu của trình biên dịch sẽ "tìm" phần tử chính xác mà bạn đang đề cập đến. Do đó, bạn có thể tăng tốc biên dịch bằng cách chính xác hơn ... mặc dù nó sẽ không đáng kể (có nhiều công việc tốn nhiều thời gian hơn trong C++, giống như mở tất cả những thứ đó).

Vì (trong trường hợp này) bạn đang đề cập đến cùng một phần tử, nó nên không quan trọng.


Giờ đây, có thể thực hiện song song thú vị với ngôn ngữ thông dịch. Trong một ngôn ngữ diễn giải, tra cứu tên sẽ bị trì hoãn đến thời điểm mà dòng (hoặc hàm) được gọi. Vì vậy, nó có thể có tác động vào thời gian chạy (mặc dù một lần nữa, có lẽ không thực sự đáng chú ý).

Các vấn đề liên quan