ページへ戻る
印刷
技術系備忘録/C++/最適化小手先テクニック/try~throw~catchの乱用を避けるべし
をテンプレートにして作成 ::
シンクリッジ
xpwiki
:技術系備忘録/C++/最適化小手先テクニック/try~throw~catchの乱用を避けるべし をテンプレートにして作成
開始行:
通説ですが、try~throw~catch は遅いです。
便利に使える場面もありますが、パフォーマンスが気になると...
どの程度のパフォーマンスかを実際に調べてみました。
-List1
#prettify{{
class CTest
{
public:
enum{
TABLESIZE = 100,
};
int m_Table[TABLESIZE];
public:
CTest();
int CaseGoto();
int CaseTry();
virtual void OnExcept(){}
};
CTest::CTest()
{
::memset(m_Table,0,sizeof(m_Table));
m_Table[0] = 1;
}
int CTest::CaseGoto()
{
int nCount = 0;
for(int i=0; i<1000000; i++ ){
for(int x=0; x<TABLESIZE; x++ ){
if( m_Table[x] != 0 ){
OnExcept(); // 最適化されないように念のため
goto next; // throwと比較しやすいようにgoto使ってます
}
}
nCount++;
next:;
}
return nCount;
}
int CTest::CaseTry()
{
int nCount = 0;
for(int i=0; i<1000000; i++ ){
try{
for(int x=0; x<TABLESIZE; x++ ){
if( m_Table[x] != 0 ){
OnExcept(); // 最適化されないように念のため
throw false;
}
}
nCount++;
}catch(...){
}
}
return nCount;
}
}}
CTest::CaseGoto と CTest::CaseTry の処理時間をそれぞれ計...
CTest::CaseGoto が 10ms、
CTest::CaseTry が 7551ms、
と、サンプルコードが特殊ではありますが、かなりの差があり...
(Pentium3 1.2G のマシンでVC++6を使用)
try~catch は、関数をまたいで goto 出来るうえ、ローカルク...
例外処理本来の意味で、深いネスト(関数)からエラー処理の為...
さらに、ちょっと愚痴っぽくなりますが、
本来 goto文 を使うべき箇所(*1)で、goto文 を避ける為に try...
VisualC++ を使ってデバッガ上で実行すると、throw が発生す...
開発業務等で外部提供のモジュールを使用するケースはよくあ...
その外部モジュールが、通常フローにも関わらず throw 連発し...
出力ウインドウが"例外処理・・・"で埋め尽くされてしまいま...
自分で入れたデバッグメッセージは一瞬で流されて見れたもん...
どうにかならないもんでしょうか・・・って誰にも文句を言え...
なにはともあれ、try~catch を何も考えずに使うのは止めたほ...
/*
setjmp はメモリ上にスタック環境を保持しておき、longjmp で...
その為か setjmp~longjmp は特殊で難しく、コードの見通しも...
C++では try~catch として言語仕様としてサポートされた訳で...
そう考えると、C言語の時代でも setjmp~longjmp をもっと便...
*/
/*
本件は C++ における try~catchのパフォーマンスについて述...
JAVA や C# は try~catch を使うことが大前提のような仕様に...
*/
----
*1 goto文は使ってはいけないとか、場合によっては使う...
終了行:
通説ですが、try~throw~catch は遅いです。
便利に使える場面もありますが、パフォーマンスが気になると...
どの程度のパフォーマンスかを実際に調べてみました。
-List1
#prettify{{
class CTest
{
public:
enum{
TABLESIZE = 100,
};
int m_Table[TABLESIZE];
public:
CTest();
int CaseGoto();
int CaseTry();
virtual void OnExcept(){}
};
CTest::CTest()
{
::memset(m_Table,0,sizeof(m_Table));
m_Table[0] = 1;
}
int CTest::CaseGoto()
{
int nCount = 0;
for(int i=0; i<1000000; i++ ){
for(int x=0; x<TABLESIZE; x++ ){
if( m_Table[x] != 0 ){
OnExcept(); // 最適化されないように念のため
goto next; // throwと比較しやすいようにgoto使ってます
}
}
nCount++;
next:;
}
return nCount;
}
int CTest::CaseTry()
{
int nCount = 0;
for(int i=0; i<1000000; i++ ){
try{
for(int x=0; x<TABLESIZE; x++ ){
if( m_Table[x] != 0 ){
OnExcept(); // 最適化されないように念のため
throw false;
}
}
nCount++;
}catch(...){
}
}
return nCount;
}
}}
CTest::CaseGoto と CTest::CaseTry の処理時間をそれぞれ計...
CTest::CaseGoto が 10ms、
CTest::CaseTry が 7551ms、
と、サンプルコードが特殊ではありますが、かなりの差があり...
(Pentium3 1.2G のマシンでVC++6を使用)
try~catch は、関数をまたいで goto 出来るうえ、ローカルク...
例外処理本来の意味で、深いネスト(関数)からエラー処理の為...
さらに、ちょっと愚痴っぽくなりますが、
本来 goto文 を使うべき箇所(*1)で、goto文 を避ける為に try...
VisualC++ を使ってデバッガ上で実行すると、throw が発生す...
開発業務等で外部提供のモジュールを使用するケースはよくあ...
その外部モジュールが、通常フローにも関わらず throw 連発し...
出力ウインドウが"例外処理・・・"で埋め尽くされてしまいま...
自分で入れたデバッグメッセージは一瞬で流されて見れたもん...
どうにかならないもんでしょうか・・・って誰にも文句を言え...
なにはともあれ、try~catch を何も考えずに使うのは止めたほ...
/*
setjmp はメモリ上にスタック環境を保持しておき、longjmp で...
その為か setjmp~longjmp は特殊で難しく、コードの見通しも...
C++では try~catch として言語仕様としてサポートされた訳で...
そう考えると、C言語の時代でも setjmp~longjmp をもっと便...
*/
/*
本件は C++ における try~catchのパフォーマンスについて述...
JAVA や C# は try~catch を使うことが大前提のような仕様に...
*/
----
*1 goto文は使ってはいけないとか、場合によっては使う...
ページ名: