2008-11-21 40 views
18

Bao nhiêu sử dụng con trỏ thông minh, đặc biệt là tăng :: shared_ptr có chi phí cao hơn so với con trỏ trần về mặt thời gian và bộ nhớ? Có sử dụng con trỏ trần tốt hơn cho các bộ phận chuyên sâu về hiệu năng của hệ thống chơi game/nhúng không? Bạn có khuyên bạn nên sử dụng con trỏ trần hoặc con trỏ thông minh cho các thành phần chuyên sâu hiệu suất?C++ Hiệu suất con trỏ thông minh

Trả lời

21

dereferencing con trỏ thông minh thường là tầm thường, chắc chắn cho tăng trong chế độ phát hành. Tất cả các kiểm tra tăng cường là lúc biên dịch. (Con trỏ thông minh có thể trong lý thuyết làm công cụ thông minh trên các chủ đề). Điều này vẫn còn rất nhiều hoạt động khác. Nicola đã đề cập đến việc xây dựng, sao chép và hủy diệt. Tuy nhiên, đây không phải là bộ hoàn chỉnh. Các hoạt động quan trọng khác là hoán đổi, gán và đặt lại thành NULL. Về cơ bản, mọi hoạt động đòi hỏi sự thông minh.

Lưu ý rằng một số thao tác này bị loại trừ bởi một số con trỏ thông minh. Ví dụ. boost::scoped_ptr thậm chí không thể được sao chép, hãy để một mình được chỉ định. Vì điều này làm giảm hoạt động, việc triển khai có thể được tối ưu hóa cho các phương thức này ít hơn.

Thực tế, với TR1 sắp xuất hiện, có khả năng trình biên dịch có thể làm tốt hơn với con trỏ thông minh hơn con trỏ thô. Ví dụ. có thể là một trình biên dịch có thể chứng minh rằng một con trỏ không thể sao chép thông minh không được đặt bí danh trong một số trường hợp, chỉ vì nó không thể sao chép được. Hãy suy nghĩ về nó: răng cưa xảy ra khi hai con trỏ được tạo ra trỏ đến cùng một đối tượng. Nếu con trỏ đầu tiên không thể được sao chép, làm thế nào một con trỏ thứ hai sẽ trỏ đến cùng một đối tượng? (Có nhiều cách xung quanh điều đó - toán tử * phải trả lại một giá trị)

+0

Thật không may, ý tưởng của bạn cho con trỏ thông minh được tối ưu hóa sẽ không hoạt động, ít nhất là trong C++. Bạn có thể đã lưu con trỏ ở nơi khác trước khi đặt con trỏ vào con trỏ thông minh. Hơn nữa, thật dễ dàng (nhưng không được khuyên) để đưa con trỏ C trở lại con trỏ thông minh, bằng cách thực hiện & * smart_ptr; –

+0

tôi đồng ý với chris jefferson. không ai ngăn bạn lưu trữ nó ở nơi khác trước khi đặt nó vào con trỏ thông minh –

+0

Tôi đã viết một câu trả lời nhỏ về việc đánh dấu bí danh ở đây: http://stackoverflow.com/questions/270408/is-it-better-in-c-to- pass-by-value-or-pass-by-constant-reference # 271344 –

7

Tăng cung cấp các con trỏ thông minh khác nhau. Nói chung cả hai bộ nhớ chiếm đóng, mà thay đổi theo loại con trỏ thông minh, và hiệu suất không phải là một vấn đề. Để so sánh hiệu suất, bạn có thể kiểm tra điều này http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smarttests.htm.

Như bạn có thể thấy chỉ xây dựng, sao chép và hủy diệt được tính đến so sánh hiệu suất, có nghĩa là dereferencing một con trỏ thông minh được cho là có cùng chi phí như của con trỏ thô.

Đoạn sau đây chứng minh rằng không có thiệt hại thực hiện bằng cách sử dụng một shared_ptr<> ở vị trí của một con trỏ liệu:

#include <iostream> 
#include <tr1/memory> 

int main() 
{ 
#ifdef USE_SHARED_PTR 
    std::tr1::shared_ptr<volatile int> i(new int(1)); 
#else 
    volatile int * i = new int(1); 
#endif 

    long long int h = 0; 

    for(long long int j=0;j < 10000000000LL; j++) 
    { 
     h += *i; 
    } 

    std::cout << h << std::endl; 
    return 0; 
} 
2

Con trỏ thông minh được tham chiếu (loại phổ biến nhất) chỉ tốn thêm chi phí khi bạn sao chép, tạo và xóa chúng. Chi phí bổ sung này có thể đáng kể nếu bạn sao chép rất nhiều, bởi vì hầu hết trong số đó là an toàn chỉ.

Nếu bạn chỉ muốn một con trỏ "tự động xóa", có nhiều auto_ptr bị bỏ qua hoặc mới và sáng bóng (nhưng chưa được hỗ trợ nhiều) unique_ptr từ C++ 0x.

2

Khi tôi thử nghiệm lần cuối, với VC6, trình biên dịch không thể tối ưu hóa mã bằng con trỏ thông minh cũng như có thể với con trỏ thô. Mọi thứ có thể đã thay đổi kể từ đó.

+2

Khi tôi cuối cùng thử nghiệm một phiên bản cũ của tăng (1.34 tôi nghĩ) với VC6, trình biên dịch tối ưu hóa sự gia tăng nguyên tử của refcount cho một weak_ptr. Điều đó làm cho mọi thứ chạy nhanh hơn đáng kể, mặc dù đã gây ra khá nhiều sự cố trong libs luồng. – Michel

+0

VC6 Tôi nhận thấy vẫn còn được sử dụng nhiều bởi các dự án lớn mà không thể dễ dàng chuyển đổi, nhưng hãy công bằng ở đây, nó không phải là một trình biên dịch trưởng thành cho đến VC2003, bản phát hành thứ 2 trong vòng đời sản phẩm VS.NET. – ApplePieIsGood

6

Cách duy nhất để giải quyết các vấn đề về hiệu suất là lập hồ sơ cho mã của bạn. Phần lớn nhất của vấn đề hiệu suất là tưởng tượng anyway; chỉ profiling sẽ chỉ ra cho bạn nơi tắc nghẽn của bạn nằm.

Nếu nó chỉ ra rằng sử dụng con trỏ thông minh tạo ra một nút cổ chai nơi con trỏ nguyên không, hãy sử dụng con trỏ thô! Cho đến lúc đó, tôi sẽ không lo lắng quá nhiều về nó; hầu hết các thao tác trên con trỏ thông minh đều rất nhanh. Bạn có thể so sánh các chuỗi quá thường xuyên (hoặc một cái gì đó như thế) cho họ quan trọng.

2

Có một nhà nửa chừng thường bị bỏ qua giữa một "thủ công" được quản lý std::vector<T*> (tức là con trỏ thô) và std::vector<boost::shared_ptr<T> >, ở dạng các lớp học boost::ptr_container.

Những kết hợp hiệu suất của một thùng chứa con trỏ thô với sự tiện lợi của một container con trỏ thông minh (tức là chúng cung cấp chức năng mọi người muốn container STL là std::auto_ptr để cung cấp, if that worked).

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