2011-01-29 8 views
1

私のコードを見ているうちに、たくさんの質問が表示されました。私はいくつかのコードスニペットについて人々がどのように考えるかを知りたい。それぞれについて、私はより最適化されたものと、より良いプラクティスまたはクリーナーとは何かを考えています。おそらく、可能な最適化はナノ秒単位で行われますが、私は理論的には不思議です。 :)Java最適化に関する質問

1)最初はエラーを報告する必要があるルーチンです。この

if(success) 
//Stuff 
else 
reportInternalError(); 

はどんな利点が唯一それが起こる初めてエラーを報告することになっている)(

if(success) { 
//Stuff 
return; 
} 
reportInternalError(); 

2)reportInternalErrorにそれを変更することのように今それが見え、それが潜在的に可能非常に頻繁に呼ばれる。現在のところ、それは最後の1が重複したコードについてです私は

if(reported) 
return; 
//Report error 
reported = true; 

3にそれを変更する方法について考えています。この

if(!reported) { 
//Report error 
reported = true; 
} 

)のようなものです。私は正確に同じコードを2回使用しています。私はそれを書く良い方法を見つけようとしています。

first = true; 
do { 
try { 
    //Stuff 
} catch() { 
    if(!first) 
     loop = false; 
} 
first = false; 
} while(loop); 

おかげ対

try { 
//Stuff 
} catch(){ 
} 

while(loop) { 
try { 
    //Same Stuff 
} catch(){ 
    loop = false; 
} 
} 

+1

、実行時のパフォーマンスの違いは信じられないほどnegible誰も気づかないだろうになります:私はシンプルbreaktargetExceptionWasThrownの交換についてのフェンスの上です。 )理論的には時間の無駄だから理論的に考えるべきではありません; – delnan

答えて

2

を私はマイクロの最適化を介して可読性と保守性にプレミアムを置きます。マイクロ最適化から得られる利益は、実際には怠っています(今日のコンパイラ、JIT、プロセッサの高度化を考えると、しばしばゼロです)。

私の選択肢:

1) は、私がメインのコードパスおよび支店での例外ケースに沿って、通常のケースを入れてみてください:

if (! success) { 
    reportInternalError(); 
} 

// Stuff 

2) 私は、独創的なアプローチを好みます。もう1つの方法は、メソッドが常にreturnになりたいと仮定していますが、今後さらに処理する必要がある場合はどうなりますか?私は余分なものが支店に行きたくない:

if (! reported) { 
    // Report error 
    reported = true; 
} 
// extra stuff to do 

3) リファクタリングしたバージョンは、私にはより保守ようです。正しい

boolean isFirstIteraton = true; 
boolean targetExceptionWasThrown = false; 
do { 
    try { 
     //Stuff 
    } catch() { 
     if (! isFirstIteraton) { 
      targetExceptionWasThrown = true; 
     } 
    } 
    isFirstIteraton = false; 
} while (! targetExceptionWasThrown); 
+0

ありがとう、あなたはあなたの選択肢の多くを正当化しました。 –

+1

@ケビンS - ありがとう。私は論理的根拠が重要だと思う:(1)私は誤りがあり、私に訂正してもらいたい。 (2)すべてのケースをカバーすることを行うための絶対的な正しい方法はありません - あなたはいつ逸脱するのかを知るための論理的根拠を知る必要があります。 –

4

心配しないでください。この時代では、コンピュータのパワーは脳のパワーよりもずっと安いので、可読性のためにコードを最適化してください。おそらく数マイクロ秒の時間がかかることはありません。

さらに、JVMのJITコンパイラは、これらの最適化を行う可能性が最も高いでしょう。たとえそうでなくても、パフォーマンスが向上したように見える修正が非常に複雑になっているため、プログラムの速度が遅くなる可能性があります。ジョシュ・ブロッホは、昨年Devoxxで優秀なpresentationをこのテーマに与えました。

+3

私のプログラミング教師の一人は、これに関して良いことを言っていました: "コンパイラを超越しようとしないでください" – esaj

2

#3に関して、例外はループを '終了'します。try-catchをループの外側に置くだけです。

try { 
//Stuff 
} catch(){ 
} 

try { 
    while(true) { 
    //Same Stuff 
    } 
} catch(){ 
} 

しかし、あなたは重複のいくつかの量を持っているので、第二の例ではbreakを採用する(代わりにloop VARの)方がよいかもしれません。

first = true; 
while (true) { 
try { 
    //Stuff 
} catch() { 
    if(!first) 
     break; 
} 
first = false; 
}; 

それ以外の場合は、//Stuffの別の方法を作成できます。それは最初の例の明快さを保存しますが、重複を取り除きます。

1

非常に低レベルのコード(アセンブリ言語の特別なマイクロプロセッサ)を記述しない限り、そのような改良はパフォーマンスに与える影響はありません。私は可読性が高いレベルでより重要であることに同意します。

+0

アドバイスありがとうこれは私がすでに知っていることであり、OPで言及しているものです。私は本当に具体的な答えを探していました。 –

1

理論的にも実際的にも、コンパイラはこの種のマイクロ最適化を処理する必要があります。代わりに明快さに焦点を当てて、単一のリターンイディオムに固執する:すべての関数/メソッドは、最後に1つのreturnステートメントを持つ必要があります。

第3の例では、try/catchブロックを少なくとも2回実行しようとしています。お試しください。

for (int i=0; i<2 || loop; i++) { 
    // put the try/catch block here 
} 
1

私は、パフォーマンスのためにコンパイラーを凌駕しようとするべきではなく、読みやすさに重点を置いてください。私はケース1と2を持っているときに私が使用することはこれです:

ケース1:

if(! success) { 
    reportInternalError(); 
    return; 
} 

// do Stuff 

及びケース2について:

if(reported) 
return; 

//Report error 
reported = true; 

基本的にガード句パターンです。 http://www.c2.com/cgi/wiki?GuardClause。これは、コードを実行する前にいくつかの不変条件が満たされていることを確認したいときに適切に機能します。私は、この場合、複数の返品ルールを破ることはできないと思います。そして、コードを読みやすくするために、コードを実行する前にどのような条件を満たしているかを一目で確認することができます。

#3に関しては、私は次のように記述します。

try { 

     boolean finished = false; 
     do { 

      //Same Stuff 

      if (/* end of loop test */) { 
       finished = true; 
      } 
     } while (! finished); 
    } catch() { 
     // handle exception  
    }