Exceptions trong C ++ có thực sự chậm không


98

Tôi đã xem Xử lý lỗi có hệ thống trong C ++ - Andrei Alexandrescu , anh ấy tuyên bố rằng Ngoại lệ trong C ++ rất chậm.

Điều này có còn đúng với C ++ 98 không?


42
Không có ý nghĩa gì khi hỏi liệu "C ++ 98 exceptions" có nhanh hơn / chậm hơn "C ++ 03 exceptions" hoặc "C ++ 11 exceptions" hay không. Hiệu suất của chúng phụ thuộc vào cách trình biên dịch triển khai chúng trong chương trình của bạn và tiêu chuẩn C ++ không nói gì về cách chúng nên được triển khai; yêu cầu duy nhất là hành vi của họ phải tuân theo tiêu chuẩn (quy tắc "as-if").
In silico

Câu hỏi có liên quan (nhưng không thực sự trùng lặp): stackoverflow.com/questions/691168/…
Philipp

2
vâng, nó rất chậm, nhưng chúng không nên được ném cho các hoạt động bình thường hoặc được sử dụng như một chi nhánh
BЈовић 12/12/12

Tôi đã tìm thấy một câu hỏi tương tự .
PaperBirdMaster 12/12/12

Để làm rõ những gì BЈовић đã nói, việc sử dụng các ngoại lệ không phải là điều đáng sợ. Đó là khi một ngoại lệ được ném ra mà bạn gặp phải (có khả năng) các hoạt động tốn thời gian. Tôi cũng tò mò về lý do tại sao bạn muốn biết cụ thể đối với C ++ 89 ... phiên bản mới nhất đó là C ++ 11 và thời gian để các ngoại lệ chạy được xác định thực hiện, do đó 'có khả năng' tốn thời gian của tôi .
thecoshman 12/12/12

Câu trả lời:


162

Mô hình chính được sử dụng ngày nay cho các ngoại lệ (Itanium ABI, VC ++ 64 bit) là các ngoại lệ của mô hình Zero-Cost.

Ý tưởng là thay vì mất thời gian bằng cách thiết lập một người bảo vệ và kiểm tra rõ ràng sự hiện diện của các ngoại lệ ở mọi nơi, trình biên dịch tạo ra một bảng phụ ánh xạ bất kỳ điểm nào có thể ném một ngoại lệ (Bộ đếm chương trình) vào danh sách các trình xử lý. Khi một ngoại lệ được ném ra, danh sách này sẽ được tham khảo để chọn trình xử lý phù hợp (nếu có) và ngăn xếp không được liên kết.

So với if (error)chiến lược thông thường :

  • mô hình Zero-Cost, như tên của nó, là miễn phí khi không có ngoại lệ nào xảy ra
  • nó có giá khoảng 10x / 20x một lần ifkhi một ngoại lệ xảy ra

Tuy nhiên, chi phí không phải là nhỏ để đo lường:

  • Bảng phụ thường lạnh và do đó việc tìm nạp nó từ bộ nhớ sẽ mất nhiều thời gian
  • Xác định trình xử lý phù hợp liên quan đến RTTI: nhiều bộ mô tả RTTI để tìm nạp, nằm rải rác quanh bộ nhớ và các hoạt động phức tạp để chạy (về cơ bản là một dynamic_castbài kiểm tra cho mỗi trình xử lý)

Vì vậy, phần lớn bộ nhớ cache bị bỏ sót, và do đó không nhỏ so với mã CPU thuần túy.

Lưu ý: để biết thêm chi tiết, hãy đọc báo cáo TR18015, chương 5.4 Xử lý ngoại lệ (pdf)

Vì vậy, có, các ngoại lệ chậm trên con đường ngoại lệ , nhưng về mặt khác, chúng nhanh hơn so với kiểm tra rõ ràng ( ifchiến lược) nói chung.

Lưu ý: Andrei Alexandrescu có vẻ hỏi điều này "nhanh hơn". Cá nhân tôi đã thấy mọi thứ xoay chuyển theo cả hai cách, một số chương trình nhanh hơn với các ngoại lệ và những chương trình khác nhanh hơn với các nhánh, vì vậy thực sự có vẻ như mất khả năng tối ưu hóa trong một số điều kiện nhất định.


Có vấn đề gì không?

Tôi sẽ khẳng định nó không. Một chương trình nên được viết với tính dễ đọc chứ không phải hiệu suất (ít nhất, không phải là tiêu chí đầu tiên). Các ngoại lệ được sử dụng khi người ta cho rằng người gọi không thể hoặc sẽ không muốn xử lý lỗi ngay tại chỗ và chuyển nó lên ngăn xếp. Phần thưởng: trong C ++ 11, các ngoại lệ có thể được sắp xếp giữa các luồng bằng Thư viện chuẩn.

Mặc dù vậy, điều này khá tinh tế, tôi khẳng định rằng map::findkhông nên ném nhưng tôi ổn với việc map::findtrả về một checked_ptrcái ném nếu nỗ lực bỏ tham chiếu nó không thành công vì nó vô hiệu: trong trường hợp thứ hai, như trong trường hợp của lớp mà Alexandrescu đã giới thiệu, người gọi chọn giữa kiểm tra rõ ràng và dựa vào các ngoại lệ. Trao quyền cho người gọi mà không giao thêm trách nhiệm cho anh ta thường là một dấu hiệu của thiết kế tốt.


3
+1 Tôi sẽ chỉ bổ sung bốn điều: (0) về hỗ trợ cho việc lặp lại được thêm vào trong C ++ 11; (1) tham chiếu đến báo cáo của ủy ban về hiệu quả c ++; (2) một số nhận xét về tính đúng đắn (như thậm chí có thể đọc được); và (3) về hiệu suất, nhận xét về việc đo lường nó so với trường hợp không sử dụng ngoại lệ (tất cả chỉ là tương đối)
Cheers and hth. - Alf

2
@ Cheersandhth.-Alf: (0), (1) và (3) done: cảm ơn. Về tính đúng đắn (2), mặc dù nó vượt trội về khả năng đọc nhưng tôi không chắc chắn về các ngoại lệ dẫn đến mã đúng hơn các chiến lược xử lý lỗi khác (rất dễ quên về nhiều đường dẫn vô hình của các ngoại lệ thực thi được tạo ra).
Matthieu M.

2
Mô tả có thể đúng cục bộ, nhưng có thể đáng chú ý rằng sự hiện diện của các ngoại lệ có ý nghĩa toàn cầu đối với các giả định và tối ưu hóa mà trình biên dịch có thể thực hiện. Những tác động này gây ra vấn đề là chúng "không có ví dụ phản đối tầm thường", vì trình biên dịch luôn có thể nhìn xuyên qua một chương trình nhỏ. Lập hồ sơ trên một cơ sở mã lớn, thực tế có và không có ngoại lệ có thể là một ý tưởng hay.
Kerrek SB,

4
> mô hình Zero-Cost, như tên của nó, là miễn phí khi không có ngoại lệ nào xảy ra, điều này không thực sự đúng với mức độ chi tiết tốt nhất. Việc tạo ra nhiều mã hơn luôn có tác động đến hiệu suất, ngay cả khi nhỏ và tinh vi ... có thể mất một chút thời gian để hệ điều hành tải tệp thực thi hoặc bạn sẽ nhận được nhiều lần bỏ lỡ i-cache hơn. ngoài ra, những gì về mã mở ngăn xếp? Ngoài ra, còn những thí nghiệm mà bạn có thể làm để đo lường tác động thay vì cố gắng hiểu nó bằng suy nghĩ hợp lý thì sao?
jheriko

2
@jheriko: Tôi tin rằng tôi đã thực sự giải quyết hầu hết các câu hỏi của bạn. Thời gian tải không nên bị ảnh hưởng (không nên tải mã nguội), không nên tác động đến i-cache (mã nguội không được đưa vào bộ nhớ đệm i), ... vì vậy, để giải quyết một câu hỏi còn thiếu: "cách đo" => thay thế bất kỳ ngoại lệ nào được đưa ra bằng lệnh gọi tới abortsẽ cho phép bạn đo dấu chân kích thước nhị phân và kiểm tra xem thời gian tải / i-cache có hoạt động tương tự hay không. Tất nhiên, tốt hơn là không đánh bất kỳ abort...
Matthieu M.

60

Khi câu hỏi được đăng, tôi đang trên đường đến bác sĩ, có một chiếc taxi đang đợi, vì vậy tôi chỉ có thời gian cho một bình luận ngắn. Nhưng bây giờ đã nhận xét và ủng hộ và phản đối, tôi tốt hơn nên thêm câu trả lời của riêng mình. Ngay cả khi câu trả lời của Matthieu đã là khá tốt.


Các ngoại lệ có đặc biệt chậm trong C ++ so với các ngôn ngữ khác không?

Yêu cầu lại

“Tôi đã xem Xử lý lỗi có hệ thống trong C ++ - Andrei Alexandrescu , anh ấy tuyên bố rằng Ngoại lệ trong C ++ rất chậm.”

Nếu đó là những gì Andrei tuyên bố theo đúng nghĩa đen, thì anh ấy đã rất hiểu lầm, nếu không muốn nói là hoàn toàn sai lầm. Đối với một trường hợp ngoại lệ được nâng / ném ra luôn chậm so với các thao tác cơ bản khác trong ngôn ngữ, bất kể ngôn ngữ lập trình . Không chỉ trong C ++ trở lên trong C ++ mà còn trong các ngôn ngữ khác, như tuyên bố có mục đích chỉ ra.

Nói chung, hầu hết là bất kể ngôn ngữ nào, hai tính năng cơ bản của ngôn ngữ có thứ tự cấp độ chậm hơn so với phần còn lại, vì chúng dịch sang các lệnh gọi của các quy trình xử lý các cấu trúc dữ liệu phức tạp, là

  • ném ngoại lệ và

  • cấp phát bộ nhớ động.

Đáng mừng là trong C ++, người ta thường có thể tránh được cả hai mã quan trọng về thời gian.

Thật không may, không có điều đó như một bữa trưa miễn phí , ngay cả khi hiệu quả mặc định của C ++ đến khá gần. :-) Đối với hiệu quả đạt được bằng cách tránh ném ngoại lệ và cấp phát bộ nhớ động thường đạt được bằng cách mã hóa ở mức độ trừu tượng thấp hơn, sử dụng C ++ chỉ là một “C tốt hơn”. Và tính trừu tượng thấp hơn có nghĩa là “độ phức tạp” lớn hơn.

Độ phức tạp cao hơn có nghĩa là dành nhiều thời gian hơn cho việc bảo trì và ít hoặc không có lợi ích từ việc sử dụng lại mã, đó là chi phí tiền tệ thực tế, ngay cả khi khó ước tính hoặc đo lường. Tức là, với C ++, người ta có thể, nếu muốn, đánh đổi một số hiệu quả của lập trình viên để lấy hiệu quả thực thi. Làm như vậy hay không phần lớn là một quyết định về kỹ thuật và cảm nhận của bản thân, bởi vì trên thực tế, chỉ có thể dễ dàng ước tính và đo lường được lợi nhuận chứ không phải chi phí.


Có bất kỳ thước đo khách quan nào về hiệu suất ném ngoại lệ C ++ không?

Có, ủy ban tiêu chuẩn hóa C ++ quốc tế đã xuất bản Báo cáo kỹ thuật về hiệu suất C ++, TR18015 .


Điều đó có nghĩa là gì khi các trường hợp ngoại lệ “chậm”?

Về cơ bản, điều đó có nghĩa là a throwcó thể mất rất nhiều thời gian ™ so với ví dụ như một intbài tập, do việc tìm kiếm trình xử lý.

Như TR18015 thảo luận trong phần 5.4 “Ngoại lệ”, có hai chiến lược thực hiện xử lý ngoại lệ chính,

  • cách tiếp cận trong đó mỗi try-block tự động thiết lập bắt ngoại lệ, để thực hiện tìm kiếm chuỗi trình xử lý động khi một ngoại lệ được đưa ra và

  • cách tiếp cận mà trình biên dịch tạo ra các bảng tra cứu tĩnh được sử dụng để xác định trình xử lý cho một ngoại lệ được ném.

Cách tiếp cận tổng quát và rất linh hoạt đầu tiên gần như bị bắt buộc trong Windows 32-bit, trong khi ở 64-bit và * nix-land, cách tiếp cận thứ hai hiệu quả hơn rất nhiều thường được sử dụng.

Cũng như báo cáo đó thảo luận, đối với mỗi cách tiếp cận, có ba lĩnh vực chính mà việc xử lý ngoại lệ ảnh hưởng đến hiệu quả:

  • try-block,

  • các chức năng thông thường (cơ hội tối ưu hóa) và

  • throw-biểu thức.

Về cơ bản, với phương pháp xử lý ngoại lệ động (Windows 32-bit), việc xử lý ngoại lệ có tác động đến trycác khối, chủ yếu là bất kể ngôn ngữ nào (vì điều này bị ép buộc bởi lược đồ Xử lý ngoại lệ có cấu trúc của Windows ), trong khi phương pháp tiếp cận bảng tĩnh có chi phí gần như bằng không cho try- các khối. Thảo luận về điều này sẽ tốn nhiều không gian và nghiên cứu hơn là thực tế để có câu trả lời SO. Vì vậy, hãy xem báo cáo để biết chi tiết.

Thật không may, báo cáo từ năm 2006, đã hơi lỗi thời vào cuối năm 2012, và theo tôi biết thì không có bất cứ thứ gì mới hơn có thể so sánh được.

Một quan điểm quan trọng khác là tác động của việc sử dụng các ngoại lệ đối với hiệu suất rất khác với hiệu quả riêng biệt của các tính năng ngôn ngữ hỗ trợ, bởi vì, như báo cáo lưu ý,

“Khi xem xét việc xử lý ngoại lệ, nó phải được đối chiếu với các cách xử lý lỗi khác.”

Ví dụ:

  • Chi phí bảo trì do các kiểu lập trình khác nhau (tính đúng đắn)

  • ifKiểm tra lỗi trang web cuộc gọi dự phòng so với kiểm tra tập trungtry

  • Các vấn đề về bộ đệm (ví dụ: mã ngắn hơn có thể nằm trong bộ đệm)

Báo cáo có một danh sách các khía cạnh khác nhau cần xem xét, nhưng dù sao thì cách thực tế duy nhất để có được những thông tin khó về hiệu quả thực thi có lẽ là triển khai cùng một chương trình bằng cách sử dụng ngoại lệ và không sử dụng ngoại lệ, trong một giới hạn quyết định về thời gian phát triển và với các nhà phát triển quen thuộc với từng cách, và sau đó ĐO LƯỜNG .


Cách tốt để tránh chi phí ngoại lệ là gì?

Tính đúng đắn hầu như luôn luôn vượt trội hơn hiệu quả.

Không có ngoại lệ, những điều sau có thể dễ dàng xảy ra:

  1. Một số mã P có nghĩa là để lấy một tài nguyên hoặc tính toán một số thông tin.

  2. Mã gọi C lẽ ra phải được kiểm tra thành công / thất bại, nhưng không.

  3. Tài nguyên không tồn tại hoặc thông tin không hợp lệ được sử dụng trong mã theo sau C, gây ra tình trạng hỗn loạn chung.

Vấn đề chính là điểm (2), trong đó với lược đồ mã trả về thông thường, gọi C không bị buộc phải kiểm tra.

Có hai cách tiếp cận chính buộc phải kiểm tra như vậy:

  • Trường hợp P trực tiếp ném một ngoại lệ khi nó không thành công.

  • Trong đó P trả về một đối tượng mà C phải kiểm tra trước khi sử dụng giá trị chính của nó (nếu không thì là một ngoại lệ hoặc kết thúc).

Cách tiếp cận thứ hai là AFAIK, được Barton và Nackman mô tả lần đầu tiên trong cuốn sách của họ * Khoa học và Kỹ thuật C ++: Giới thiệu về Kỹ thuật và Ví dụ Nâng cao , trong đó họ giới thiệu một lớp được gọi Fallowcho một kết quả hàm “khả thi”. Một lớp tương tự được gọi optionalhiện được cung cấp bởi thư viện Boost. Và bạn có thể dễ dàng Optionaltự mình triển khai một lớp, sử dụng std::vectorgiá trị mang trong trường hợp kết quả không phải POD.

Với cách tiếp cận đầu tiên, mã gọi C không có lựa chọn nào khác ngoài việc sử dụng các kỹ thuật xử lý ngoại lệ. Tuy nhiên, với cách tiếp cận thứ hai, bản thân mã gọi C có thể quyết định xem nên thực hiện ifkiểm tra dựa trên hay xử lý ngoại lệ chung. Do đó, cách tiếp cận thứ hai hỗ trợ việc đánh đổi giữa hiệu quả thời gian lập trình và thực thi.


Tác động của các tiêu chuẩn C ++ khác nhau đối với hiệu suất ngoại lệ là gì?

“Tôi muốn biết điều này có còn đúng với C ++ 98 không”

C ++ 98 là tiêu chuẩn C ++ đầu tiên. Đối với các trường hợp ngoại lệ, nó đã giới thiệu một hệ thống phân cấp tiêu chuẩn của các lớp ngoại lệ (tiếc là không hoàn hảo). Tác động chính đến hiệu suất là khả năng xảy ra các đặc tả ngoại lệ (bị loại bỏ trong C ++ 11), tuy nhiên, chúng không bao giờ được trình biên dịch Windows C ++ chính thực hiện đầy đủ. Visual C ++: Visual C ++ chấp nhận cú pháp đặc tả ngoại lệ C ++ 98, nhưng chỉ bỏ qua thông số kỹ thuật ngoại lệ.

C ++ 03 chỉ là một phiên bản kỹ thuật của C ++ 98. Điểm mới thực sự duy nhất trong C ++ 03 là khởi tạo giá trị . Không liên quan gì đến ngoại lệ.

Với các đặc tả ngoại lệ chung tiêu chuẩn C ++ 11 đã bị loại bỏ và thay thế bằng noexcepttừ khóa.

Tiêu chuẩn C ++ 11 cũng bổ sung hỗ trợ để lưu trữ và ném lại các ngoại lệ, điều này rất tốt để truyền các ngoại lệ C ++ trên các lệnh gọi lại ngôn ngữ C. Hỗ trợ này hạn chế hiệu quả cách thức lưu trữ ngoại lệ hiện tại. Tuy nhiên, theo như tôi biết thì điều đó không ảnh hưởng đến hiệu suất, ngoại trừ mức độ xử lý ngoại lệ mã mới hơn có thể dễ dàng được sử dụng hơn trên cả hai mặt của lệnh gọi lại ngôn ngữ C.


6
"exceptions luôn chậm so với các hoạt động cơ bản khác trong ngôn ngữ, bất kể ngôn ngữ lập trình" ... ngoại trừ trong các ngôn ngữ được thiết kế để biên dịch việc sử dụng các ngoại lệ thành điều khiển luồng thông thường.
Ben Voigt

4
"ném một ngoại lệ liên quan đến cả cấp phát và giải nén ngăn xếp". Điều đó rõ ràng là không đúng nói chung và, một lần nữa, OCaml là một ví dụ phản bác. Trong các ngôn ngữ đã thu gom rác, không cần phải giải phóng ngăn xếp vì không có trình hủy, do đó bạn chỉ cần longjmpđến trình xử lý.
JD

2
@JonHarrop: có lẽ bạn không biết rằng Pyhon có điều khoản cuối cùng để xử lý ngoại lệ. điều này có nghĩa là một triển khai Python có chức năng giải nén ngăn xếp hoặc không phải là Python. bạn dường như hoàn toàn không biết gì về các chủ đề mà bạn tuyên bố (tưởng tượng). lấy làm tiếc.
Chúc mừng và hth. - Alf

2
@ Cheersandhth.-Alf: "Pyhon có mệnh đề cuối cùng để xử lý ngoại lệ. Điều này có nghĩa là một triển khai Python hoặc có chức năng tháo cuộn ngăn xếp hoặc không phải là Python". Cấu try..finallytrúc có thể được thực hiện mà không cần tháo cuộn. F #, C # và Java đều triển khai try..finallymà không cần sử dụng tính năng giải nén ngăn xếp. Bạn chỉ cần longjmpxử lý (như tôi đã giải thích).
JD

4
@JonHarrop: bạn có vẻ như đang đặt ra một tình huống tiến thoái lưỡng nan. nhưng nó không có liên quan gì tôi có thể thấy với bất cứ điều gì được thảo luận cho đến nay, và cho đến nay bạn đã đăng một chuỗi dài những điều vô nghĩa nghe có vẻ tiêu cực . Tôi sẽ phải tin tưởng bạn để đồng ý hay không với một số từ ngữ mơ hồ, bởi vì với tư cách là kẻ phản diện, bạn đang lựa chọn những gì bạn sẽ tiết lộ rằng nó "có nghĩa", và tôi chắc chắn không tin tưởng bạn sau tất cả những điều vô nghĩa vô nghĩa, từ chối, v.v.
Chúc mừng và hth. - Alf

13

Bạn không bao giờ có thể khẳng định về hiệu suất trừ khi bạn chuyển đổi mã thành lắp ráp hoặc điểm chuẩn cho nó.

Đây là những gì bạn thấy: (băng ghế dự bị nhanh)

Mã lỗi không nhạy cảm với tỷ lệ xuất hiện. Các trường hợp ngoại lệ có một chút chi phí miễn là chúng không bao giờ được ném. Một khi bạn ném chúng đi, sự khốn khổ bắt đầu. Trong ví dụ này, nó được ném cho 0%, 1%, 10%, 50% và 90% các trường hợp. Khi các ngoại lệ được ném 90% thời gian, mã chậm hơn 8 lần so với trường hợp các ngoại lệ được ném 10% thời gian. Như bạn thấy, các ngoại lệ thực sự rất chậm. Không sử dụng chúng nếu chúng bị ném thường xuyên. Nếu ứng dụng của bạn không có yêu cầu về thời gian thực, hãy ném chúng đi nếu chúng rất hiếm khi xảy ra.

Bạn thấy nhiều ý kiến ​​trái chiều về chúng. Nhưng cuối cùng, các trường hợp ngoại lệ có chậm không? Tôi không phán xét. Chỉ cần xem điểm chuẩn.

Tiêu chuẩn hiệu suất ngoại lệ C ++


12

Nó phụ thuộc vào trình biên dịch.

Ví dụ, GCC được biết đến là có hiệu suất rất kém khi xử lý các ngoại lệ, nhưng điều này đã trở nên tốt hơn đáng kể trong vài năm qua.

Nhưng lưu ý rằng việc xử lý các ngoại lệ nên - như tên đã nói - là ngoại lệ chứ không phải là quy tắc trong thiết kế phần mềm của bạn. Khi bạn có một ứng dụng ném quá nhiều ngoại lệ mỗi giây đến mức nó ảnh hưởng đến hiệu suất và đây vẫn được coi là hoạt động bình thường, thì bạn nên nghĩ đến việc làm mọi thứ khác đi.

Các ngoại lệ là một cách tuyệt vời để làm cho mã dễ đọc hơn bằng cách loại bỏ tất cả các mã xử lý lỗi khó hiểu, nhưng ngay khi chúng trở thành một phần của quy trình chương trình bình thường, chúng trở nên thực sự khó theo dõi. Hãy nhớ rằng a throwđược goto catchngụy trang khá nhiều .


-1 lại câu hỏi như bây giờ, "điều này vẫn đúng với C ++ 98", điều đó chắc chắn không phụ thuộc vào trình biên dịch. ngoài ra, câu trả lời throw new Exceptionnày là một Java-ism. một quy tắc nên không bao giờ ném con trỏ.
Chúc mừng và hth. - Alf

1
tiêu chuẩn 98 có quy định chính xác cách thực hiện các ngoại lệ không?
thecoshman

6
C ++ 98 là một tiêu chuẩn ISO, không phải là một trình biên dịch. Có rất nhiều trình biên dịch thực hiện nó.
Philipp

3
@thecoshman: Không. Tiêu chuẩn C ++ không nói gì về cách mọi thứ nên được triển khai (ngoại trừ có thể có phần "Giới hạn triển khai" của tiêu chuẩn).
Trong silico

2
@Insilico thì tôi chỉ có thể rút ra kết luận hợp lý rằng (thật đáng ngạc nhiên) nó được triển khai được xác định (đọc, trình biên dịch cụ thể) cách các ngoại lệ hoạt động.
thecoshman 12/12/12

4

Có, nhưng điều đó không quan trọng. Tại sao?
Đọc phần này:
https://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

Về cơ bản, điều đó nói rằng việc sử dụng các ngoại lệ như Alexandrescu đã mô tả (giảm tốc 50 lần vì họ sử dụng catchnhư else) là sai. Điều đó đang được nói đối với ppl, những người thích làm như vậy, tôi ước C ++ 22 :) sẽ thêm một cái gì đó như:
(lưu ý rằng đây sẽ phải là ngôn ngữ cốt lõi vì về cơ bản nó là trình biên dịch tạo mã từ hiện có)

result = attempt<lexical_cast<int>>("12345");  //lexical_cast is boost function, 'attempt'
//... is the language construct that pretty much generates function from lexical_cast, generated function is the same as the original one except that fact that throws are replaced by return(and exception type that was in place of the return is placed in a result, but NO exception is thrown)...     
//... By default std::exception is replaced, ofc precise configuration is possible
if (result)
{
     int x = result.get(); // or result.result;
}
else 
{
     // even possible to see what is the exception that would have happened in original function
     switch (result.exception_type())
     //...

}

PS cũng lưu ý rằng ngay cả khi các ngoại lệ chậm đến mức đó ... nó không phải là vấn đề nếu bạn không dành nhiều thời gian cho phần đó của mã trong quá trình thực thi ... Ví dụ: nếu phân chia float chậm và bạn làm cho nó gấp 4 lần nhanh hơn, điều đó không thành vấn đề nếu bạn dành 0,3% thời gian của mình để thực hiện phân chia FP ...


0

Giống như trong silico cho biết việc triển khai của nó phụ thuộc vào, nhưng nói chung các ngoại lệ được coi là chậm đối với bất kỳ triển khai nào và không nên được sử dụng trong mã chuyên sâu về hiệu suất.

CHỈNH SỬA: Tôi không nói là không sử dụng chúng nhưng đối với mã chuyên sâu về hiệu suất, tốt nhất là nên tránh chúng.


9
Đây tốt nhất là một cách rất đơn giản để xem xét hiệu suất ngoại lệ. Ví dụ: GCC sử dụng triển khai "không tốn phí" trong đó bạn không bị ảnh hưởng về hiệu suất nếu không có ngoại lệ nào được đưa ra. Và các ngoại lệ dành cho các trường hợp đặc biệt (tức là hiếm), vì vậy ngay cả khi chúng bị chậm bởi một số chỉ số thì vẫn không đủ lý do để không sử dụng chúng.
In silico

@insilico nếu bạn nhìn vào lý do tại sao tôi đã nói, tôi đã không nói rằng không sử dụng các trường hợp ngoại lệ hoàn toàn. Tôi đã chỉ định mã chuyên sâu về hiệu suất, đây là một đánh giá chính xác, tôi chủ yếu làm việc với gpgpus và tôi sẽ bị bắn nếu tôi sử dụng ngoại lệ.
Chris McCabe
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.