2013-04-05 28 views
6

Một số người nói: "Bất kỳ hoạt động nào có thể đạt được bằng cách lập chỉ mục mảng cũng có thể được thực hiện với con trỏ. Phiên bản con trỏ nói chung sẽ nhanh hơn".Hiệu quả giữa con trỏ và mảng (hướng dẫn lắp ráp ít hơn không mất ít thời gian hơn)

tôi nghi ngờ về kết quả trên, vì vậy tôi làm bài kiểm tra sau:

Trong bài viết sau, chúng tôi không quan tâm biên dịch tối ưu hóa. Về biên dịch tối ưu hóa như thế nào làm ảnh hưởng đến hiệu quả giữa con trỏ và mảng, xin lưu ý: Efficiency: arrays vs pointers

(Visual Studio 2010, Debug Mode, không tối ưu)

#include <windows.h> 
#include <stdio.h> 

int main() 
{ 
    int a[] = {10,20,30}; 
    int* ap = a; 

    long counter; 

    int start_time, end_time; 
    int index; 

    start_time = GetTickCount(); 
    for (counter = 1000000000L; counter>0; counter--) 
    { 
     *(ap+1) = 100; 
    } 
    end_time = GetTickCount(); 
    printf("10 billion times of *ap = %d\n", end_time-start_time); 

    start_time = GetTickCount(); 
    for (counter = 1000000000L; counter>0; counter--) 
    { 
     a[1] = 101; 
    } 
    end_time = GetTickCount(); 
    printf("10 billion times of a[0] = %d\n", end_time-start_time); 

    return 0; 
} 

kết quả là:

10 billion times of *ap = 3276 
10 billion times of a[0] = 3541 

Con trỏ có vẻ hơi nhanh. Nhưng sau khi tôi đã so sánh dis-lắp ráp, tôi rơi vào một sự nhầm lẫn sâu hơn.

(Visual Studio 2010, Debug Mode, không tối ưu)

; 17 :   *(ap+1) = 100; 
mov eax, DWORD PTR _ap$[ebp] 
mov DWORD PTR [eax+4], 100   ; 00000064H 

; 25 :   a[1] = 101; 
mov DWORD PTR _a$[ebp+4], 101  ; 00000065H 

Từ lắp ráp đầu ra, truy cập bộ nhớ thông qua một con trỏ mất 2 hướng dẫn và mảng chỉ mất 1 lệnh.

Tại sao mảng thực thi ít hướng dẫn hơn nhưng không mất nhiều thời gian hơn con trỏ?

Có liên quan đến bộ nhớ cache cpu không? Làm cách nào tôi có thể sửa đổi mã thử nghiệm của mình để chứng minh?

+6

không bao giờ tối ưu hóa ở chế độ Gỡ lỗi ... – TemplateRex

+2

Nhiều năm trước, tôi đã thử nghiệm chính xác điều này. Phiên bản lập chỉ mục mảng nhanh hơn. Tuyên bố là rác, hoặc có thể nhanh hơn, nó chỉ phụ thuộc. – john

+0

Nó chỉ phụ thuộc ... vào phần cứng? – Philip

Trả lời

2

Thứ nhất và quan trọng nhất là ngôn ngữ C không có tốc độ. Ví dụ, C không có tốc độ, nhưng trình biên dịch GCC tạo mã có thể thay đổi về tốc độ từ mã được trình biên dịch Clang tạo ra, và cả hai đều có khả năng tạo ra mã mà thực hiện hành vi do trình thông dịch Cint hoặc Ch tạo ra. Tất cả những điều này là C triển khai. Một số người trong số họ chậm hơn so với những người khác, nhưng tốc độ không thể được quy cho C trong anyway!

6.3.2.1 của chuẩn C nói:

Trừ khi nó là toán hạng của toán tử sizeof, các nhà điều hành _Alignof , hoặc & toán tử đơn hạng, hoặc là một chuỗi chữ sử dụng để khởi tạo một mảng, biểu thức có loại '' mảng kiểu '' là được chuyển đổi thành biểu thức có loại '' con trỏ thành loại '' trỏ thành phần tử ban đầu của đối tượng mảng và không phải là một giá trị.

này nên được một dấu hiệu cho thấy cả hai *(ap+1)a[1] trong mã của bạn là hoạt động con trỏ. Bản dịch này sẽ xảy ra trong giai đoạn biên dịch trong Visual Studio. Do đó, điều này không ảnh hưởng đến thời gian chạy.

6.5.2.1 liên quan đến "mảng subscripting" nói:

Một trong những biểu thức có trách nhiệm gõ '' con trỏ để hoàn thành đối tượng gõ '', khái niệm khác có kiểu số nguyên, và kết quả có kiểu ' 'kiểu''. Điều này dường như chỉ ra rằng mảng subscript điều hành thực sự là một nhà điều hành con trỏ ...

Đây là xác nhận rằng ap[1] thực sự là một hoạt động con trỏ, như chúng ta mặc nhiên công nhận trước đó. Tuy nhiên, trong thời gian chạy, mảng đã được dịch sang một con trỏ. Hiệu suất phải giống nhau.

... vậy, tại sao chúng không giống nhau?

Đặc điểm của hệ điều hành bạn đang sử dụng là gì? Đó không phải là hệ điều hành đa nhiệm, đa người dùng phải không? Giả sử hệ điều hành đã hoàn thành vòng lặp đầu tiên mà không bị gián đoạn, nhưng sau đó ngắt vòng lặp thứ hai và chuyển điều khiển sang một quy trình khác. Sự gián đoạn này có làm mất hiệu lực thử nghiệm của bạn không? Làm cách nào để đo tần suất và thời gian gián đoạn do chuyển đổi tác vụ gây ra? Lưu ý rằng điều này sẽ khác nhau đối với các HĐH khác nhau và HĐH là một phần của việc triển khai .

Các đặc tính của CPU bạn đang sử dụng là gì? Liệu nó có bộ nhớ cache nội bộ nhanh, riêng cho mã máy? Giả sử toàn bộ vòng lặp đầu tiên của bạn, và nó bao gồm cơ chế thời gian để phù hợp với bộ đệm mã độc đáo, nhưng vòng lặp thứ hai đã bị cắt ngắn. Điều này sẽ không dẫn đến việc thiếu bộ nhớ cache và chờ đợi lâu trong khi CPU của bạn lấy phần còn lại của mã từ RAM không? Làm cách nào để đo thời gian gián đoạn do bộ nhớ cache bị xóa? Lưu ý rằng điều này sẽ khác nhau đối với các CPU khác nhau và CPU là một phần của việc triển khai .

Những câu hỏi này phải nêu ra một số câu hỏi như "Điểm chuẩn tối ưu hóa vi mô này có giải quyết được vấn đề quan trọng hoặc có ý nghĩa không?". Sự thành công của một tối ưu hóa sẽ khác nhau tùy thuộc vào kích thước và độ phức tạp của vấn đề. Tìm một vấn đề quan trọng, giải quyết nó, lập hồ sơ giải pháp, tối ưu hóa nó và cấu hình lại nó. Bằng cách đó, bạn có thể cung cấp thông tin có ý nghĩa về phiên bản được tối ưu hóa nhanh hơn bao nhiêu là. Sếp của bạn sẽ hạnh phúc hơn nhiều với bạn, với điều kiện bạn không tiết lộ rằng các tối ưu hóa có lẽ chỉ liên quan đến việc thực hiện của bạn, như tôi đã đề cập trước đó. Tôi chắc chắn bạn sẽ thấy rằng ít nhất của những lo lắng của bạn sẽ là dereference mảng vs dereference con trỏ.

+0

@GrijeshChauhan Cảm ơn. Tôi đánh giá cao định dạng, nhưng các chỉnh sửa khác không chính xác hoặc không đáng kể. Tôi có nghĩa là "[cint] (http://root.cern.ch/drupal/content/cint)". Có hai cách chính xác để đánh vần "hành vi": [Cách người Mỹ-Anh] (http://www.merriam-webster.com/dictionary/behavior) và [theo cách của người Anh] (http: //www.merriam) -webster.com/dictionary/behaviour). Xin vui lòng, không đi ra khỏi con đường của bạn để sửa chữa điều đó. Bạn sẽ kết thúc với viêm khớp nhanh hơn bạn nhận ra ... – Sebivor

+0

Ooh..Xin lỗi cho điều đó .. Đó là do nhầm lẫn..BTW lời giải thích tốt đẹp Vì vậy, tôi đã quan tâm. –

+0

@lvalue Kết quả khác nhau có thể bị ảnh hưởng bởi bộ nhớ cache cpu, nhưng làm thế nào để chứng minh điều đó? – ajaxhe

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