2009-04-08 21 views

Trả lời

14

Đã đo được - 10 triệu cuộc gọi mất khoảng 50 giây. Tôi nghĩ rằng đó là chi phí đáng kể cho chức năng không sử dụng.

Sử dụng một macro có thể giúp thoát khỏi điều này trong phiên bản build:

#ifdef _DEBUG 
    #define LOGMESSAGE(str) OutputDebugString(str); 
#else 
    #define LOGMESSAGE(str) 
#endif 

Không chỉ loại bỏ các cuộc gọi, mà còn các thông số đánh giá và các chuỗi văn bản hoàn toàn bị loại bỏ và bạn sẽ không nhìn thấy chúng trong tệp nhị phân.

4

Tại sao không tự đánh giá? Biên dịch mã sau, chạy nó & thời gian nó. Sau đó, loại bỏ các cuộc gọi đến OutputDebugString, biên dịch lại và chạy lại. Nên mất ba phút của bạn thời gian.

#include <windows.h> 

    int main() { 
     const int COUNT = 1000000; 
     int z = 0;  
     for (unsigned int i = 0; i < COUNT; i++) { 
      z += i; 
      OutputDebugString("foo"); 
     } 
     return z; 
    } 
+4

Lưu ý rằng chỉ chạy mã này không phải là toàn bộ câu chuyện. Hiệu suất sẽ được xác định chủ yếu bởi những gì đang giám sát đầu ra gỡ lỗi (DebugView, trình gỡ lỗi Visual Studio, v.v.), và có thể khác nhau tùy thuộc vào phiên bản Windows bạn đang chạy, vì vậy bạn cần kiểm tra trong nhiều trường hợp khác nhau. Nó sẽ mất nhiều hơn ba phút thời gian của một người. –

+1

Tôi đã thử nghiệm đoạn mã trên bằng cách sử dụng thời gian của người nghèo (NULL) - bắt đầu. 1000.000 lần mất 13 giây nếu bật OutputDebugString, nhưng không có trình gỡ rối đính kèm, nếu mở DbgViewer để nắm bắt đầu ra, thời gian là 169 giây. Nếu tắt OutputDebugString, thời gian đo được là 0 giây. – zhaorufei

8

Tôi chưa gặp sự cố trong hàng tá ứng dụng chế độ phát hành phía máy chủ trong nhiều năm, tất cả đều có số liệu tích hợp. Bạn có thể nhận được ấn tượng rằng nó chậm vì hầu hết các ứng dụng trình gỡ rối bạn có thể tìm thấy (DBWIN32 và các cộng sự) khá chậm khi đưa dữ liệu lên màn hình, tạo ra ấn tượng về độ trễ. Tất nhiên tất cả các ứng dụng của chúng tôi có đầu ra này bị vô hiệu hóa theo mặc định, nhưng hữu ích để có thể bật nó trên thực địa, vì sau đó bạn có thể xem đầu ra gỡ lỗi từ một số ứng dụng, được tuần tự hóa trong một cái gì đó như DBWin32 . Đây có thể là một kỹ thuật gỡ lỗi rất hữu ích cho các lỗi liên quan đến các ứng dụng giao tiếp.

+0

+1 cho _is hữu ích để có thể bật tính năng này trong trường_ –

9

Tôi đã đọc trong một bài viết mà OutPutDebugString nội bộ làm vài điều thú vị:

  1. Tạo \ Mở mutex và chờ đợi vô hạn đến mutex được mua lại.
  2. Chuyển dữ liệu giữa ứng dụng và trình gỡ lỗi được thực hiện qua một đoạn 4kbyte bộ nhớ dùng chung, với Mutex và hai đối tượng Sự kiện bảo vệ quyền truy cập vào nó.

Ngay cả khi trình gỡ rối không được đính kèm (trong chế độ phát hành), chi phí đáng kể liên quan đến việc sử dụng OutputDebugstring với việc sử dụng các đối tượng hạt nhân khác nhau.

Hiển thị hiệu suất rất hiển nhiên nếu bạn viết mã mẫu và kiểm tra.

6

Không bao giờ để các cuộc gọi OutputDebugString() trong bản phát hành bản phát hành. Luôn xóa chúng bằng cách sử dụng câu lệnh #ifdef hoặc cung cấp một công tắc khác để tắt chúng.

Nếu bạn để chúng vào, hãy tắt chúng theo mặc định và chỉ kích hoạt chúng theo yêu cầu, bởi vì nếu không ứng dụng của bạn sẽ khó gỡ lỗi các ứng dụng khác hoạt động tốt (tức là chỉ xuất dữ liệu gỡ lỗi theo yêu cầu).

Theres DebugView để nắm bắt đầu ra của ứng dụng, nhưng tất nhiên điều đó chỉ tốt nếu không phải mọi ứng dụng đều chen chúc cùng không có lý do chính đáng.

10

Tôi đang viết này lâu sau khi câu hỏi này đã được trả lời, nhưng câu trả lời cho bỏ lỡ một khía cạnh nhất định:

OutputDebugString có thể khá nhanh khi không có ai đang lắng nghe để sản lượng của nó.Tuy nhiên, có một người nghe chạy trong nền (có thể là DbgView, DBWin32, Visual Studio, vv) có thể làm cho nó chậm hơn 10 lần (nhiều hơn trong môi trường MT). Lý do khiến những người nghe này móc sự kiện báo cáo và việc xử lý sự kiện của họ được thực hiện trong phạm vi của lệnh gọi OutputDebugString. Hơn nữa, nếu một số chủ đề gọi OutputDebugString đồng thời, chúng sẽ được đồng bộ hóa. Để biết thêm thông tin, hãy xem Watch out: DebugView (OutputDebugString) & Performance. Một lưu ý phụ, tôi nghĩ rằng trừ khi bạn đang chạy một ứng dụng thời gian thực, bạn không nên lo lắng về một cơ sở mất 50 giây để chạy các cuộc gọi 10 triệu. Nếu nhật ký của bạn chứa 10M mục, 50 giây lãng phí là ít nhất trong số các vấn đề của bạn, bây giờ bạn phải phân tích bằng cách nào đó con thú. Một bản ghi 10K có vẻ hợp lý hơn nhiều, và việc tạo ra sẽ chỉ mất 0,05 giây theo phép đo của người chia vạch.

Vì vậy, nếu đầu ra của bạn có kích thước hợp lý, việc sử dụng OutputDebugString sẽ không làm bạn tổn thương đến mức đó. Tuy nhiên, hãy nhớ rằng sự chậm lại sẽ xảy ra khi một người nào đó trên hệ thống bắt đầu nghe kết quả này.

2

Tôi đã tò mò về chủ đề này vì vậy tôi đã làm một số nghiên cứu.

Tôi đã đăng kết quả, mã nguồn và tệp dự án để bạn có thể lặp lại các thử nghiệm cho thiết lập của mình. Bao gồm chạy một ứng dụng chế độ phát hành mà không cần bất cứ điều gì giám sát OutputDebugString và sau đó với Visual Studio 6, Visual Studio 2005 và Visual Studio 2010 giám sát OutputDebugString để xem những gì khác biệt trong hiệu suất có cho mỗi phiên bản của Visual Studio.

kết quả thú vị, Visual Studio 2010 quá trình OutputDebugString thông tin lên đến 7 lần chậm hơn so với Visual Studio 6.

Full bài viết ở đây: Whats the cost of OutputDebugString?

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