C++ の例外処理に関する質問です。

try, catch, throw による例外処理はメモリーの使用効率が悪いという理由で、C のように関数の復帰値による例外処理をしている(*1)人達がいるのですが、本当に関数の復帰値による例外処理よりもメモリーの使用効率は悪いのでしょうか?
また、悪い場合どれくらい悪いのでしょうか?
*1…例外内容は別途管理しています。

回答の条件
  • 1人2回まで
  • 登録:2008/02/27 13:31:13
  • 終了:2008/03/03 12:15:31

回答(3件)

id:t_shiono No.1

t_shiono回答回数256ベストアンサー獲得回数222008/02/27 22:54:59

ポイント32pt

質問の流れにそって、メモリ効率の低下という意味では2つの可能性があると思います。

1.throwされるオブジェクトのメモリ効率

catch節で、値渡し、参照渡し、ポインタ渡しのどれでも自由に受け取ることができます。

ただし、throwされたオブジェクトのコピーが送出されます。その分だけ無駄なメモリを使うといえます。

2.コードサイズに関わるメモリ効率

例外処理を使うと、例外処理にかかる処理の分だけコードサイズが大きくなります。

プログラムサイズが大きくなれば、その分だけメモリ効率は低下するといえるかもしれません。


これらの差というのは、リソース制約が厳しい世界においては大きな問題となるでしょう。

そうでなければ、*パフォーマンス的な意味では*問題にならないと個人的には思います。

だからといって、例外はC++の主たる要素ではありますが、的確に使うことが非常に難しい仕様であることも確かです。

*1の人達がどういった人達か分かりませんが、リソース制約が厳しい世界の開発者であったり、あるいは、その仕様の難しさ故に、チームとして一定の水準のコードを保つためには、例外を使用しない方がよいと考えているのではないでしょうか?


例外については、More Effective C++の例外の章を読むと理解が深まると思います。

何かの参考になれば。

id:Bookmarker

throw するオブジェクトと例外処理を行う try, catch, throw 文がメモリーを使用するのは当然ですが、それが C のような例外処理と比べて効率が悪いのかという質問です。

私は以下のように思っているのですが、間違っているでしょうか?

・throw するオブジェクト

関数の復帰値+別途管理する例外内容と同程度だと思います。

・throw 文

例外内容を設定する処理+関数の復帰値を返す処理と同程度だと思います。

→ 実はオブジェクトの転送処理での使用効率が悪い?

・try, catch 文

関数の呼び出し毎に処理するより、try, catch 文でまとめて処理する方が使用効率が良いと思います。

→ 実は一つの try, catch 文での使用効率がかなり悪い?

2008/02/28 02:13:26
id:pyopyopyo No.2

pyopyopyo回答回数341ベストアンサー獲得回数832008/02/28 02:31:14

ポイント32pt

例外処理のオーバヘッドに関する話題は良く聞きますね

http://oshiete1.goo.ne.jp/kotaeru.php3?q=1790955

http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja...

少なくとも,例外処理を使うと

  • 例外処理のためのコード
  • 例外処理のためのメモリ

が必要になることは事実です.つまり処理時間とメモリ使用量が増加する可能性があります

後者のmsdnの記事でも

このファイルは 23,040 バイトから 29,696 バイトになりました

と例外を使うと,バイナリのサイズが増加する実例が挙げられています.

(この記事が書かれたのは1999年で少々古いデータですが,最近のコンパイラでも例外処理にはオーバヘッドが伴います)

このオーバヘッドが多いとみるか,少ないと見るかは,状況によりますが,

少なくとも,

  • メリット 例外処理を上手につかうと生産性が向上する
  • デメリット 例外処理にはオーバヘッドが伴う

という点はふまえておいた方が良いと思います.

id:Bookmarker

同上。

2008/02/28 12:48:45
id:t_shiono No.3

t_shiono回答回数256ベストアンサー獲得回数222008/02/29 05:32:38

ポイント16pt

先に挙げたMore Effecive C++など、詳しい議論は参照してください。

簡単に、コメントに対して答えると。

> ・throw するオブジェクト

> 関数の復帰値+別途管理する例外内容と同程度だと思います。

これはthrowするオブジェクト次第です。

一概に言えません。JavaのようにThrowableでないとthrowできないとかそういったことはないので、

関数の返り値であれば、定数を返すことも多いでしょうし、それに対応して、整数をthrowすることもできます。

そういった意味で大きな差はここについては無いかもしれません。

> ・throw 文

> 例外内容を設定する処理+関数の復帰値を返す処理と同程度だと思います。

> → 実はオブジェクトの転送処理での使用効率が悪い?

これに答えるとYesになります。先の答に書いたコピーが発生するためです。

throwされた場合でもローカルに作成されたオブジェクトなどは適切に開放されなければいけません。

それらのオブジェクトを開放するコードをコンパイラが生成しています。

これは、私も十分に詳しい訳ではないですが、最適化なども考えると、もう少し違いはありそうな気がします。

> ・try, catch 文

> 関数の呼び出し毎に処理するより、try, catch 文でまとめて処理する方が使用効率が良いと思います。

> → 実は一つの try, catch 文での使用効率がかなり悪い?

これは何を意図されたか把握しきれていないのですが、

Object o;
result = f1();
if (!result) {
  例外処理
}
result = f2();
if (!result) {
  例外処理
}

よりも

try {
  Object o;
  f1();
  f2();
} catch (例外1) {
} catch (例外2) {
}

となっていて、コードも分かりやすいので、実行コードもシンプルになっているのではないか?ということでしょうか?

もし、そういう意味であれば、答はNoです。

前者の手続き的なプログラムは最適化こそされ、基本的にそのままの動作を実行するコードが生成されます。

それに対し、後者のtry-catchの方は例外処理がうまく実行するようにコードが色々変わります。

例えばですが、f1で例外が発生した場合は、oを解体してcatchブロックのアドレスXXXにジャンプするということを覚えておくような処理などです。

そのため、コード上はシンプルですが、内部的にはもう少しややこしくなるはずです。


上記のように、それらの視点で比較すれば、メモリ効率の差はあることはあります。

また、その効率の低下を可能な限り押さえる方法もあることにはあります。

「質問がメモリ効率が悪い」という視点からのものでしたので、あまり触れませんでしたが、例外処理の仕組みはコードを見て分かる動作よりもずっと複雑です。そのため、それを適切に利用することはC++が使えますという開発者のうちほんの一部の人だと思っています。

それ以外の人が例外処理を利用すると、C++が大人の言語と呼ばれる側面が顔を出してきます。

この質問への反応(ブックマークコメント)

トラックバック

  • C言語でtry-catchを実現する方法 かってに回答 2008-02-27 22:38:51
    【質問】 try, catch, throw による例外処理はメモリーの使用効率が悪いという理由で、 C のように関数の復帰値による例外処理をしている(*1)人達がいるのですが、本当に関数の復帰値による例
「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません