2010-03-15 29 views
115

tôi đã gặp phải những đoạn như sau:gỡ lỗi vs hiệu suất phát hành

“Debug vs phát hành thiết lập trong IDE khi bạn biên dịch mã của bạn trong Visual Studio làm cho hầu như không có sự khác biệt với hiệu suất ... mã được tạo ra là hầu như giống nhau. Trình biên dịch C# không thực sự thực hiện bất kỳ tối ưu hóa nào. Trình biên dịch C# chỉ phun ra IL ... và tại thời gian chạy nó là JITer thực hiện tất cả các tối ưu hóa. JITer không có chế độ Debug/Release và tạo ra sự khác biệt lớn về hiệu năng. Nhưng điều đó không có key off cho dù bạn chạy Debug hoặc Thả cấu hình của dự án của bạn, đó là các phím tắt cho dù một trình gỡ lỗi được đính kèm.”

Nguồn là here và podcast là here.

Ai đó có thể hướng dẫn tôi đến một bài viết của Microsoft có thể thực sự chứng minh điều này không?

Googling "C# debug vs hiệu suất phát hành" chủ yếu là trả về kết quả nói "gỡ lỗi có rất nhiều hiệu suất trúng", "phát hành được tối ưu hóa", và "không triển khai debug để sản xuất" .

+0

bản sao có thể có của [Hiệu suất khác biệt giữa bản dựng gỡ lỗi và bản phát hành] (http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds) –

+0

Với .Net4 trên Win7-x86 , Tôi có một chương trình giới hạn CPU mà tôi đã viết chạy nhanh gần gấp 2 lần so với gỡ lỗi không có xác nhận/etc trong vòng lặp chính. – Bengie

+0

Ngoài ra, nếu bạn quan tâm đến việc sử dụng bộ nhớ, có thể có sự khác biệt lớn. Tôi đã nhìn thấy một trường hợp một dịch vụ Windows đa luồng được biên dịch trong chế độ gỡ lỗi được sử dụng 700MB cho mỗi luồng, so với 50MB cho mỗi luồng trong bản dựng Bản phát hành. Gỡ lỗi xây dựng nhanh chóng hết bộ nhớ trong điều kiện sử dụng điển hình. –

Trả lời

87

một phần là đúng sự thật. Trong chế độ gỡ lỗi, trình biên dịch phát ra các biểu tượng gỡ lỗi cho tất cả các biến và biên dịch mã như vậy. Trong chế độ phát hành một số tối ưu hóa bao gồm:

  • biến không sử dụng không được biên soạn ở tất cả
  • một số biến vòng lặp được lấy ra khỏi vòng lặp bởi trình biên dịch nếu chúng được chứng minh là bất biến
  • mã được viết dưới #debug chỉ thị không được bao gồm, v.v.

Phần còn lại phụ thuộc vào JIT.

Edit: danh sách đầy đủ của tối ưu hóa here kê biếu không của Eric Lippert

+10

Và đừng quên Debug.Asserts! Trong DEBUG xây dựng, nếu họ thất bại, họ sẽ ngăn chặn các chủ đề và bật lên một hộp tin nhắn. Trong bản phát hành, họ không được biên dịch chút nào. Điều này áp dụng cho tất cả các phương pháp có [ConditionalAttribute]. –

+13

Trình biên dịch C# không thực hiện tối ưu hóa cuộc gọi đuôi; jitter không. Nếu bạn muốn có danh sách chính xác những gì trình biên dịch C# thực hiện khi chuyển đổi tối ưu hóa được bật, hãy xem http://blogs.msdn.com/ericlippert/archive/2009/06/11/what-does-the-optimize-switch- do.aspx –

+0

ups. bạn đúng Eric. Tôi sẽ xóa nó khỏi bài viết –

9

Tôi không thể nhận xét về hiệu suất nhưng lời khuyên “không triển khai gỡ lỗi cho sản xuất” vẫn chỉ đơn giản là vì mã gỡ lỗi thường có một vài điều khác biệt trong các sản phẩm lớn. Đối với một điều, bạn có thể có các công tắc gỡ lỗi đang hoạt động và cho một thiết bị khác có thể sẽ có các kiểm tra độ chính xác bổ sung dư thừa và các đầu ra gỡ lỗi không thuộc mã sản xuất.

+0

Tôi đồng ý với bạn về vấn đề đó, nhưng điều này không trả lời được câu hỏi chính – sagie

+5

@sagie: vâng, tôi biết điều đó nhưng tôi nghĩ rằng vấn đề vẫn đáng làm. –

2

Trong msdn trang web ...

phát hành so với cấu hình gỡ lỗi

Trong khi bạn vẫn đang làm việc trên dự án của bạn , bạn thường sẽ tạo ứng dụng bằng cách sử dụng cấu hình gỡ lỗi , vì điều nàyCấu hìnhcho phép bạn xem giá trị của các biến số và kiểm soát thực thi trong trình gỡ lỗi. Bạn có thể cũng tạo và thử nghiệm các bản dựng trong cấu hình phát hành để đảm bảo rằng bạn chưa giới thiệu bất kỳ lỗi nào mà chỉ hiển thị trên một loại hình dựng hoặc mục còn lại. Trong .NET Framework lập trình, lỗi như vậy là rất hiếm, nhưng chúng có thể xảy ra.

Khi bạn đã sẵn sàng để phân phối ứng dụng của bạn cho người dùng cuối, tạo một build phát hành, sẽ được nhiều nhỏ hơn và thường sẽ có hiệu suất nhiều tốt hơn so với tương ứng cấu hình debug. Bạn có thể đặt cấu hình xây dựng trong ngăn tác vụ của Trình thiết kế dự án hoặc trong thanh công cụ Xây dựng. Để biết thêm thông tin , hãy xem Xây dựng cấu hình.

5

Từ msdn social

Nó không phải là tài liệu tốt, đây là những gì Tôi biết. Trình biên dịch phát ra một phiên bản của hệ thống .Diagnostics.DebuggableAttribute. Trong phiên bản gỡ lỗi, thuộc tính IsJitOptimizerEnabled là Đúng, trong phiên bản phát hành là Sai. Bạn có thể thấy thuộc tính này trong lắp ráp manifest với Ildasm.exe

Trình biên dịch JIT sử dụng thuộc tính này để vô hiệu hóa tối ưu mà sẽ làm gỡ khó khăn. Những cái di chuyển mã xung quanh như cẩu bất biến vòng lặp. Trong các trường hợp được chọn , điều này có thể tạo sự khác biệt lớn về hiệu suất. Không thường xuyên.

Điểm ngắt bản đồ để thực thi địa chỉ là công việc của trình gỡ lỗi. Nó sử dụng tệp .pdb và thông tin do trình biên dịch JIT tạo ra cung cấp hướng dẫn IL mã ánh xạ địa chỉ. Nếu bạn viết trình gỡ rối của riêng mình, bạn sẽ sử dụng ICorDebugCode :: GetILToNativeMapping().

Về cơ bản việc triển khai gỡ lỗi sẽ chậm hơn do tối ưu hóa trình biên dịch JIT bị tắt.

3

Những gì bạn đọc là khá hợp lệ. Bản phát hành thường là nạc do tối ưu hóa JIT, không bao gồm mã gỡ lỗi (#IF DEBUG hoặc [Có điều kiện ("DEBUG")]), tải xuống biểu tượng gỡ lỗi tối thiểu và thường không được xem là lắp ráp nhỏ hơn sẽ giảm thời gian tải. Hiệu suất khác nhau rõ ràng hơn khi chạy mã trong VS vì PDB và biểu tượng mở rộng hơn được tải, nhưng nếu bạn chạy nó một cách độc lập, sự khác biệt về hiệu suất có thể ít rõ ràng hơn. Một số mã sẽ tối ưu hóa tốt hơn so với các mã khác và nó đang sử dụng cùng một cách tối ưu hóa giống như trong các ngôn ngữ khác.

Scott có một lời giải thích tốt về phương pháp tối ưu hóa inline here

Xem this article đó đưa ra một giải thích ngắn gọn lý do tại sao nó là khác nhau trong môi trường ASP.NET cho gỡ lỗi và phát hành thiết lập.

+0

Lời giải thích nội tuyến là rất tốt – sagie

3

Một điều bạn nên lưu ý, liên quan đến hiệu suất và liệu trình gỡ lỗi có được đính kèm hay không, điều gì đó khiến chúng tôi ngạc nhiên.

Chúng tôi đã có một đoạn mã, liên quan đến nhiều vòng lặp chặt chẽ, dường như mất vĩnh viễn để gỡ lỗi, nhưng vẫn chạy khá tốt.Nói cách khác, không có khách hàng hoặc khách hàng nào gặp phải vấn đề, nhưng khi chúng tôi gỡ lỗi nó dường như chạy như mật đường.

Thủ phạm là Debug.WriteLine trong một trong các vòng lặp chặt chẽ, phát ra hàng nghìn thông điệp tường trình, còn lại từ phiên gỡ lỗi một thời gian trở lại. Dường như khi trình gỡ lỗi được đính kèm và lắng nghe đầu ra như vậy, có phí liên quan đến việc làm chậm chương trình. Đối với mã cụ thể này, nó đã được trên thứ tự của thời gian chạy 0,2-0,3 giây của riêng mình, và 30 + giây khi trình gỡ lỗi được đính kèm.

Mặc dù giải pháp đơn giản, chỉ cần xóa các thông báo gỡ lỗi không còn cần thiết nữa.

0

Ở mức độ lớn, điều đó tùy thuộc vào việc ứng dụng của bạn có bị ràng buộc tính toán hay không và cũng không phải lúc nào cũng dễ dàng biết, như trong ví dụ của Lasse. Nếu tôi có câu hỏi nhỏ nhất về những gì nó đang làm, tôi dừng lại một vài lần và kiểm tra ngăn xếp. Nếu có thêm điều gì đó mà tôi không thực sự cần, thì nó sẽ ngay lập tức.

54

Không có bài viết nào "chứng minh" bất kỳ điều gì về câu hỏi về hiệu suất. Cách để chứng minh một sự khẳng định về tác động hiệu suất của một sự thay đổi là thử cả hai cách và thử nghiệm nó trong các điều kiện thực tế nhưng được kiểm soát.

Bạn đang đặt câu hỏi về hiệu suất, vì vậy rõ ràng bạn quan tâm đến hiệu suất. Nếu bạn quan tâm đến hiệu suất thì điều đúng đắn cần làm là đặt ra một số mục tiêu hiệu suất và sau đó viết cho mình một bộ kiểm tra theo dõi tiến trình của bạn dựa trên các mục tiêu đó. Một khi bạn có một bộ thử nghiệm như vậy, bạn có thể dễ dàng sử dụng nó để kiểm tra cho chính mình sự thật hoặc sự sai lệch của các câu lệnh như "bản dựng gỡ lỗi chậm hơn".

Và hơn nữa, bạn sẽ có thể nhận được kết quả có ý nghĩa. "Chậm" là vô nghĩa bởi vì nó không rõ ràng cho dù đó là một micro giây chậm hơn hoặc hai mươi phút chậm hơn. "10% chậm hơn trong điều kiện thực tế" có ý nghĩa hơn.

Dành thời gian bạn đã dành để nghiên cứu câu hỏi này trực tuyến về cách tạo thiết bị trả lời câu hỏi. Bạn sẽ nhận được kết quả chính xác hơn rất nhiều theo cách đó. Mọi nội dung bạn đọc trực tuyến chỉ là đoán về những gì có thể xảy ra. Lý do từ những sự kiện bạn thu thập được, không phải từ những suy đoán của người khác về cách chương trình của bạn có thể hành xử như thế nào.

1

Gần đây, tôi đã gặp sự cố về hiệu suất. Danh sách sản phẩm đầy đủ đã mất quá nhiều thời gian, khoảng 80 giây. Tôi đã điều chỉnh DB, cải thiện các truy vấn và không có bất kỳ sự khác biệt nào. Tôi quyết định tạo một TestProject và tôi phát hiện ra rằng quá trình tương tự đã được thực hiện trong 4 giây. Sau đó, tôi nhận ra dự án đang ở chế độ Debug và dự án thử nghiệm đang ở chế độ Release. Tôi đã chuyển dự án chính sang Chế độ phát hành và danh sách sản phẩm đầy đủ chỉ mất 4 giây để hiển thị tất cả các kết quả.

Tóm tắt: Chế độ gỡ lỗi chậm hơn nhiều so với chế độ chạy vì nó giữ thông tin gỡ lỗi. Bạn nên luôn triển khai trong chế độ Relase. Bạn vẫn có thể có thông tin gỡ lỗi nếu bạn bao gồm tệp .PDB. Bằng cách đó bạn có thể ghi lại lỗi với số dòng, ví dụ.

+0

Bởi "chế độ chạy", bạn có nghĩa là "Phát hành"? –

+0

Vâng, chính xác. Bản phát hành không có tất cả chi phí gỡ lỗi. –

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