2011-01-07 31 views
12

Tôi muốn biết, điều gì tốt hơn hoặc nhanh hơn trong lập trình chung? Tránh ngoại lệ hoặc chờ ngoại lệ?Điều gì tốt hơn/nhanh hơn? Thử bắt hoặc tránh ngoại lệ?

Tránh các ngoại lệ sẽ là:

string a = null; 
list = someMethod(); 
if(list.Length > 0){ 
    a = list[0]; 
} 
if(a!=null) ... 

Hoặc thử bắt ngoại lệ ...

string a = null; 
try{ 
    a = someMethod()[0]; 
catch{} 
if(a!=null) ... 
+1

Hủy từ "nhanh hơn", nó không liên quan. Và đó thậm chí không phải là cách thích hợp để sử dụng try-catch vì bạn sắp xếp trolling CLR. – BoltClock

+0

chỉ là một ví dụ ... – carlosdubusm

+1

@BoltClock, không có không. Nếu trường hợp ngoại lệ xảy ra. Nó chậm hơn. – CaffGeek

Trả lời

18

Hiệu suất không phải là mối quan tâm có liên quan nhất ở đây. Câu hỏi đặt ra là, câu hỏi nào trong hai câu hỏi này dẫn đến các chương trình có thể đọc/duy trì/kiểm tra dễ đọc hơn. Bạn có thể lo lắng về hiệu suất sau này.

Nói chung, không sử dụng ngoại lệ cho điều khiển luồng. Chúng có hiệu quả là một địa phương không phải là địa phương goto mà làm cho chương trình khó đọc và làm theo. Như vậy, họ nên được dành riêng cho các tình huống đặc biệt. Nếu bạn không thể sử dụng khối try-catch để kiểm soát luồng, thì đừng. Các chương trình của bạn sẽ dễ đọc hơn và dễ bảo trì hơn.

Các "đúng" cách để xử lý tình trạng này là

var list = someMethod(); 
if(list == null || list.Length == 0) { 
    // handle something bad 
} 
string a = list[0]; 
if(a != null) { 
    // go 
} 

Bạn có thể tránh việc kiểm tra rằng list không phải là null và không có sản phẩm nào nếu có một hợp đồng (Contract.Ensures) mà đảm bảo giá trị trả về từ someMethod là không rỗng và không rỗng.

Đó là sự thật, tuy nhiên, trường hợp ngoại lệ là đắt tiền tại địa phương. Cho dù chúng có ảnh hưởng đến hiệu suất chương trình của bạn hay không (tức là, là một nút cổ chai) là một câu hỏi khác hoàn toàn. Nhưng được sử dụng đúng cách, ngoại lệ nói chung không phải là một nút cổ chai (ai quan tâm đến hiệu suất khi ứng dụng của bạn bị rơi?)

+0

Vâng, cảm ơn câu trả lời, tôi biết một điều gì đó không đúng với một thử và bắt trống. Về các chương trình có thể duy trì được là rất đúng. Có thể một ngoại lệ khác không được mong đợi có thể xảy ra và bạn sẽ không bao giờ biết. Có lẽ một bắt trống sẽ có ý nghĩa nếu bạn không quan tâm những gì ngoại lệ có thể xảy ra bạn chỉ muốn tiếp tục chạy chương trình. – carlosdubusm

+1

@carlosdumusm: Dường như bạn hiểu chính xác điều này, nhưng tôi muốn chỉ ra rằng các khối 'catch' hoặc' catch' rỗng bắt tất cả ngoại lệ (ví dụ, bắt lớp cơ sở 'Ngoại lệ ') là xấu, Xấu, XẤU. Bạn không có ý tưởng loại ngoại lệ có thể được ném nhưng bây giờ bạn đang tuyên bố rằng bạn có thể xử lý tất cả chúng.Khi mọi thứ ở trong trạng thái xấu, nhưng bạn không biết xấu hay trạng thái xấu là gì bởi vì bạn đang "xử lý" tất cả ngoại lệ, có khả năng rất nguy hiểm để tiếp tục như thể không có gì xảy ra. Xử lý những gì bạn biết bạn có thể xử lý, và nếu không nhanh chóng thất bại. – jason

+0

Vâng, có ý nghĩa, tôi có vài năm lập trình nhưng tôi có ít kiến ​​thức về ngoại lệ và đôi khi không biết phải cố gắng bắt ở đâu hoặc ở đâu để ném. Cảm ơn. – carlosdubusm

1

LUÔN LUÔN LUÔN tránh một ngoại lệ nếu bạn có thể.

Trường hợp ngoại lệ phải là ngoại lệ.

Nếu bạn có thể dự đoán nó, hãy bảo vệ chống lại nó.

Những người sử dụng các khối đánh bắt rỗng như vậy nên bị cấm sử dụng máy tính ...

Nó cũng nhanh hơn để không đi vào khối đánh bắt.

7

Trường hợp ngoại lệ rất tốn kém - nếu bạn có thể kiểm tra và tránh ngoại lệ, hãy làm như vậy.

Ngoại lệ không nên được sử dụng cho luồng chương trình thông thường.

+0

Vâng, không bao giờ nghĩ về chi phí của trường hợp ngoại lệ, cảm ơn. – carlosdubusm

0

Ném ngoại lệ là một nhiệm vụ tốn kém, vì vậy tôi sẽ luôn cố gắng và xác thực thay vì bắt. Điều này phải đủ dễ dàng để kiểm tra, tạo ra một số mã ném một ngoại lệ thông qua mỗi lần chạy và kiểm tra nó dựa vào một bộ mã tương tự kiểm tra điều kiện và đo lường hiệu suất.

Nếu mã được ghi lại bằng các chi tiết về ngoại lệ của điều kiện nào sẽ được ném, bạn sẽ có thể điều chỉnh mã gọi điện của mình. Tất nhiên bạn không thể xử lý mọi kịch bản (có thể là lỗi thời gian chạy thấp hơn?), Do đó, mã của bạn chỉ nên thực sự thử và xử lý các ngoại lệ mà nó thực sự có thể phản ứng và có thể tiếp tục.

2

Điều đó tùy thuộc. Tôi hầu như luôn luôn cố gắng tránh ngoại lệ trừ khi làm như vậy là cực kỳ tốn kém.

0

Ngoại lệ chỉ nên sử dụng cho các điều kiện đặc biệt (trừ khi không có cách nào khác), vì vậy bạn chỉ nên dùng thử/nắm bắt khi có điều gì đó bất thường xảy ra mà bạn vẫn cần xử lý (bật lên thông báo lỗi).

Có một thử/bắt cũng báo hiệu cho một lập trình viên rằng một số lỗi bên ngoài có thể xảy ra và cần được giải quyết. Trong ví dụ của bạn, list là null chỉ đơn giản là một phần bình thường của việc thực thi chương trình/luồng điều khiển và vì vậy không có gì đặc biệt về nó.

Ngoài ra, một sản phẩm hoàn toàn trống thường là một điều không tốt (dù có những tình huống giới hạn khi cần). Nó chắc chắn cần một bình luận để giải thích lý do tại sao bạn không làm bất cứ điều gì về các trường hợp ngoại lệ.

Có một useful blog post về ngoại lệ gây nhiều tranh cãi, bạn có thể thấy hữu ích

1

thuần túy từ một số quan điểm hướng dẫn/hiệu suất trên một thời gian chạy N đáng kể, tránh là tốn kém hơn, bởi vì bạn đang kiểm tra độ dài mỗi lần cho mỗi đầu vào . Ngoại lệ, chi nhánh catch chỉ được thực hiện trên sự kiện đó.

+3

Nhưng đó là SLOWER khi nó xảy ra. Nó che dấu các lỗi tiềm ẩn khác. Và đó là thực hành lập trình khủng khiếp. – CaffGeek

+1

Try-Catch không chịu chi phí nào trong luồng thông thường? Một thử nghiệm và nhảy như được sử dụng trong ví dụ này có vẻ khá rẻ về thời gian xử lý. – Derrick

+0

Đó là thực hành lập trình khủng khiếp khi nó là một 'catch {}' trống rỗng, như bạn đã nói, che giấu các lỗi lập trình khác. Và như đã đề cập, ngoại lệ nên được sử dụng cho các điều kiện đặc biệt, không phải điều gì đó xảy ra thường xuyên (ví dụ: nếu bạn biết rằng danh sách sẽ luôn rỗng khi khởi tạo và mong đợi đạt được điều đó thường xuyên, nó không còn đặc biệt nữa và bạn nên xây dựng trong séc cho nó). – Aphex

2

tất nhiên tránh ngoại lệ, hãy thử bắt dẫn đến hiệu suất bị mất.

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