Là một thử và bắt mà không ném một ngoại lệ hiệu quả hơn một điều kiện?


8

Tôi đã xem qua ví dụ này gần đây:

Nếu 999 lần trong số 1.000 ngoại lệ sẽ không được ném thì ngoại lệ chỉ được tạo một lần. Mặt khác, một điều kiện sẽ được gọi là không cần thiết 999 lần, do đó trong trường hợp này ngoại lệ là vượt trội.

Trong trường hợp này, đó là C #, nhưng nói chung điều này có đúng không? Trước đây tôi đã giả sử các câu lệnh try / Catch có chi phí riêng tương đương với thời gian xử lý một điều kiện.

Cấp, chỉ cần ném khối thử / bắt bất cứ nơi nào một điều kiện thông thường sẽ đi là một cách khủng khiếp để viết mã, nhưng thông minh tài nguyên này có giữ được không?


Trình biên dịch thực hiện thử / bắt như thế nào? Tôi nghi ngờ nó phức tạp hơn một chút so với đơn giản nếu ().
Dan Pichelman

8
Hãy thử nó. Thực sự, hãy thử nó. Tại sao bạn lại tin một số người ngẫu nhiên trên internet nói? Biết được các yếu tố phổ biến trong ngôn ngữ bạn chọn so sánh hiệu suất như thế nào cũng đáng để nỗ lực hạn chế thực hiện một thử nghiệm cẩn thận, một lần.
Kilian Foth

Tôi cảm thấy viết một so sánh hiệu suất là một nhiệm vụ rất dễ gây rối, đặc biệt là một thứ trừu tượng; cũng là ví dụ từ một cuốn sách giáo khoa C #
Jane Panda

2
Tôi sẽ đưa ra nhận xét "viết mã có thể đọc được và không tối ưu hóa sớm".
djechlin

1
@djechlin Ai đó đã phải; )
Jane Panda

Câu trả lời:


4

Nó thường đúng cho trình biên dịch chất lượng thương mại. Tuy nhiên, các điều kiện có thể đạt được hiệu quả tương tự bằng assume(false)cách sử dụng các chú thích kiểu. Tối ưu hóa hướng dẫn hồ sơ có thể đánh bại cả hai.

Lý do cơ bản là các trình biên dịch tốt có thể tạo mã hiệu quả hơn bằng cách đưa ra các giả định chính xác về khả năng mã được thực thi. Vì quy ước là các ngoại lệ là ngoại lệ, hầu hết các trình biên dịch (trong trường hợp không có dữ liệu lược tả) sẽ tạo ra mã tối ưu khi các ngoại lệ thực sự hiếm.

Ví dụ, mã xử lý ngoại lệ có thể được đặt trong phân khúc riêng của nó và chỉ được phân trang khi ngoại lệ đầu tiên xảy ra. Điều này có nghĩa là bộ đệm CPU có thể được sử dụng hiệu quả hơn, chỉ lưu trữ mã không đặc biệt.


Và các trình biên dịch động, chẳng hạn như được tìm thấy trong hầu hết tất cả các công cụ JavaScript, JVM và triển khai Smalltalk, thậm chí không cần phải đưa ra các giả định về khả năng của các nhánh, họ chỉ có thể đếm chúng. Điều đó giống như PGO trên steroid: cấu hình lại và tối ưu hóa lặp đi lặp lại nhiều lần, sử dụng khối lượng công việc thực sự đang thực thi ngay bây giờ để hướng dẫn tối ưu hóa mã đang thực thi ngay bây giờ .
Jörg W Mittag

4

Có các kịch bản để sử dụng thử / bắt và các kịch bản khác để sử dụng các điều kiện.

Sử dụng thử / bắt không gây hại cho hiệu suất như được phác thảo rộng rãi Tại đây

Tổng chi phí của một khối thử ... bắt không bao giờ xử lý ngoại lệ là một vài byte bộ nhớ

Ngoài hiệu suất, xử lý ngoại lệ thích hợp là quan trọng. Điều cuối cùng bạn muốn là các lỗi chưa được hiển thị cho người dùng, hiệu suất lỗi hoặc ứng dụng bị treo sau khi gặp sự cố.


3
Hiệu suất +1 không phải là điều quan trọng duy nhất để lo lắng hoặc chúng tôi sẽ bỏ qua các giao diện đồ họa thân thiện với người dùng trong một ví dụ
RhysW

2
Đó là một bài đọc tuyệt vời liên quan đến ngoại lệ.
Jane Panda

-1

Một ví dụ về hiệu suất tốt hơn bằng cách sử dụng thử / bắt thay vì điều kiện là khi xử lý Từ điển, khi hỏi liệu có chứa khóa là O (n) hay không chỉ cố gắng truy cập / thêm khóa và bắt ngoại lệ tiềm năng.

try
{
    dict.Add(key, val);
}
catch (Exception)
{

    dict[key] = val;
}

Wow, nếu điều này là sự thật thì tôi thực sự ngạc nhiên! Bạn đã có một tài liệu tham khảo?

5
-1. Đừng làm điều này. Nếu bạn lo ngại về chi phí hoạt động của việc kiểm tra xem khóa có tồn tại hay không, thì hãy sử dụng TryGetValue (). msdn.microsoft.com/en-us/l
Library / bb347013.aspx

cảm ơn vì đã chỉ ra rằng, điều tối thiểu tôi muốn là khuyên một thực hành tồi. Tôi đã sử dụng điều này trong một thời gian dài, tôi đoán nó đã trở nên lỗi thời. Dù sao, quan điểm của tôi là chỉ ra rằng có những kịch bản khi bắt một ngoại lệ có thể là một lựa chọn tốt hơn so với việc hỏi liệu có hợp lệ để làm điều gì đó không.
Enrique Medina
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.