3

スタックの巻き戻しが原因で、例外処理が少し高価であると人々が言うのを聞きました。

何も得られません。例外をスローするかどうか、および「リターン」を使用するかどうかにかかわらず、スタックの巻き戻しが発生します。では、違いはどこにあるのでしょうか。

たとえば、処理できないメモリの問題が発生した場合、唯一のオプションは、問題を処理または通知する必要がある領域に到達するまで機能を停止することです。では、例外をスローするための他のオプションは何ですか?

例外をスローする代わりに「リターン」を使用できますが、それは同じです。スタックの巻き戻しが 6 スタックも戻る可能性があることは知っていますが、戻り値と「戻り値」を組み合わせてチェックします。

説明を歓迎します。

4

7 に答える 7

7

return を使用すると、スタックは無条件に「巻き戻され」ます。これは、概念的には、単一の「ret」マシン コード命令を実行するのと同じくらい簡単です。例外の下では、スタックの巻き戻しは適切な例外ハンドラーを検索する必要がありますが、これははるかに複雑なタスクです。例外パスには、例外オブジェクトを構築し、おそらくコピーするタスクもありますが、これは簡単ではない場合があります。

于 2009-12-07T16:36:01.347 に答える
3

スタックの巻き戻しは、単に戻ることとは異なります。また、スタック内の各下位レベルでエラー ハンドラー (catch ブロック) を検索する必要があります。それが、それを重いプロセスにしている理由です。

そのため、本当に例外的な状況でのみ例外を使用する必要があります。例外処理に関する警告は、単に例外をスタックの上位にデータを配信する方法と見なす人向けです。「賢い」プログラミングをするのが好きな人。彼らはそれが問題を回避するための巧妙な方法だと考えていますが、その代わりに、予期していなかった 2 つの新しい問題を引き起こします。

一般に、(真に例外的な状況の場合) リターン コードではなく例外を使用することをお勧めします。これにより、コードが読みやすく、維持しやすくなります。たとえば、どちらが読みやすく、維持しやすいでしょうか?

void MyMethod()
{
    try
    {
        Method1(); 
        Method2();
        Method3();
    }
    catch(SomeException const & e) // edited per Mordachai's suggestion
    {
       // handle SomeException
    }
    catch(SomeOtherException const & e)
    {
       // handle SomeOtherException
    }
}

void MyMethod()
{
    int err;
    err = Method1();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method2();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
    err = Method3();
    switch(err)
    {
        case SOMEERRORCODE:
             // handle some error code
             break;
        case SOMEOTHERERRORCODE:
             // handle some other error code
             break;          
    }
}
于 2009-12-07T16:40:32.523 に答える
2

エラーが発生した場合のエラー処理メカニズムの速度は重要ではありません。プログラム全体のパフォーマンスに影響を与えるには、あまり頻繁に実行する必要はありません (例外的なイベントです)。

例外処理が高価であるという話は、関数が例外を発生させずに完了したときの関数のパフォーマンスへの影響について話しています。多くのコンパイラはこのオーバーヘッドをほぼゼロに減らしますが、一部のプラットフォーム、特にゲーム コンソールでは、使用可能なコンパイラまたはハードウェアが例外を適切に処理しません。

于 2009-12-07T16:40:24.460 に答える
1

例外処理がパフォーマンスに与える影響に関心がある場合は、C ++パフォーマンスに関するテクニカルレポート(特に第5.4章)を読み始めるのに最適な場所です。

于 2009-12-07T16:46:49.983 に答える
1

そもそも例外を伝えるために必要なインフラストラクチャには、わずかな「コスト」がかかります。これは、多くの人がそれを避けてRTTIを完全に無効にすることを選択するのに十分なほど重要でした. 最近では、それが問題であるとすれば、おそらく C++ はすでにあなたにとってレベルが高すぎるので、無視できるほどです ;-)

例外の伝播とスタックの巻き戻しに関しては、追加のコストがかかりますが、(a) あなたが言うように、とにかくスタックを巻き戻す必要があるため (ただし、実際にはコストがかかる場所ではありません)、(b) あなたはとにかく、追加コストがおそらく決して問題にならない例外パスにすでにあります。

例外処理のコストについて不満を言うほとんどの人は、以前はどうだったかを考えています。

于 2009-12-07T16:36:40.487 に答える
0

例外処理のほとんどのバージョンでは、コンパイラがスコープなどの問題を処理できるように、わずかな余分なオーバーヘッドが追加されます。解説付きの記事はこちら。私たちが話しているオーバーヘッドは非常に小さく、心配する価値はほとんどありません。

于 2009-12-07T16:35:21.303 に答える