2012-04-06 16 views
1

プログラミング中、私はしばしば以下のシナリオ(コードで説明)に遭遇します。ブロック内の変数を定義します。私はCの背景から来るので可能な限り変数を「ローカル」として定義すると実装が高速になりますか?

int maximumLengthOfToken = 0; 

    while(fileScanner.hasNextLine()) 
    { 
     String line; // definition 
     line = fileScanner.nextLine(); 

     Scanner lineScanner; // definition 
     lineScanner = new Scanner(line); 

     String token = lineScanner.next(); // definition and assignment 
     if(stringToMatch.endsWith(token)) 
     { 
       if(token.length() >= maximumLengthOfToken) 
        { 
        maximumLengthOfToken = token.length(); 
        builder.append(line); 
        builder.append("\n\n\n"); 
        } 
     } 
    } 
    fileScanner.close(); 

はしかし、時々、「清楚」のためにも、私は関係なく、それらが使用されているところの、上部にあるすべての変数を定義したいです。だから私は次のことをする -

int maximumLengthOfToken = 0; 
    String line; // definition 
    Scanner lineScanner; // definition 
    String token; // definition 

    while(fileScanner.hasNextLine()) 
    { 
     line = fileScanner.nextLine(); 
     lineScanner = new Scanner(line); 

     token = lineScanner.next(); // definition 

       if(stringToMatch.endsWith(token)) 
       { 
       if(token.length() >= maximumLengthOfToken) 
        { 
        maximumLengthOfToken = token.length(); 
        builder.append(line); 
        builder.append("\n\n\n"); 
        } 
     } 
    } 
    fileScanner.close(); 

"ああ、それはすごくかっこいい"と思う。

ただし、これはコードのパフォーマンスに影響しますか?最初のスタイルは速い実行コードまたは2番目のスタイルにつながりますか?また、そのような場合の条約は何ですか?私はそれが最初のスタイルだと信じています。

+0

コンパイラはこれらが同等であることを観察して、同じバイトコードにコンパイルする可能性があります。 –

+0

コンパイラが意味的に等価でないので、最初のコードを最適化しないと仮定すると、ガベージコレクションは速度の違いをもたらすでしょうか? –

+0

最初に使用される変数の宣言を考慮する必要があります。それは、コードを別の人によって簡単に推論させる。変数宣言が一番上にあり、精神的にそれらをすべて追跡しなければならないということより悪いことはありません。参照のローカリティに関するリンクと最適化コンパイラの(暗黙の)言及についてはhttp://programmers.stackexchange.com/q/56585 –

答えて

4

いいえ、パフォーマンスの違いはありません。

これが疑わしい場合は、「2000バイト離れた場合はコンピュータが変数を検索するのに200 MBまたは20バイト離れた場合よりも時間がかかりますか?答えはいいえでなければなりません。

それはあなたの変数は近い速度を向上させるかもしれない使用されている場所に変数を移動した場合には、それが使用される前にプロセッサキャッシュ(see locality)の外に低下した場合に差があるになるかもしれない唯一のケース。しかし、それが起こるためには変数とその使用の間に多くのコードが必要です。

コンパイラは、あなたのメソッドを同じバイトコードにコンパイルすることも可能です。要するに、私はあなたがそれについて心配する必要はないと思う。

+0

+1を参照してください。 –

1

これはおそらくコードのパフォーマンスには何の影響もありません - 生成されたバイトコードは同じであると思いますが、最初のバージョンは一般的に保守性と可読性が高いと考えられます。

0

一般的なケースでは、わずかな(または時には劇的な)差異が存在する可能性がありますが、Javaの場合は、標準のコンパイラチェーンではそうではありません。

コンパイラが異なる傾向にある場所は、ある範囲で定義された「varA」と、ばらばらの範囲で定義された「varB」がある場所です。コンパイラは、範囲が離れていることを観察し、両方に同じスタックスロットを割り当てます。これは、インタープリタのパフォーマンスを非常にわずかに向上させます。しかし、逆に、この手法は、何が起こったか把握するのに十分スマートでない場合、JITCで最適化が悪化する可能性があります。

0

現代のJava実装では実行時最適化を使用するため、大きな違いはありません。したがって、主に、明快さとメンテナンスの容易さに焦点を当てる必要があります。

可能な限り使用の場所にとして密接に変数を宣言するためにいくつかの理由、そこに言った:

  • 特に、非常に短い寿命(例えば、一時的な)変数を使用して、読みやすくですが。メソッドの開始までスクロールせずに、変数の型をすぐに見ることができます。

  • 可能な限り変数の範囲を制限することで、誤ったエラーの可能性を減らすことができます。ループカウンタを再利用する。

  • エスケープ解析などのいくつかの最適化では、変数のスコープができるだけ制限されているとパフォーマンスが向上する場合があります。

は追記として、私はCとJavaの両方でプログラミングしが一方から他方へのコンテキストスイッチに時折困難です。しかし、Cスタイルの慣習をJavaで(あるいはその逆に)使用することは、あまり良い考えではありません。 Cの規約は、Javaにはない制限によって決まります。コードを使用するだけで、他の人が読むことが難しくなります。

2

他の人によると、パフォーマンスに大きな違いはありません。

変数宣言をメソッドの先頭に置き、それらを使用する場所の近くに配置するかどうかを選択します。その選択にあなた自身を強制しないでください。両方を持つことができます - あなたの方法を非常に短くすることによって。あなたがこの選択に直面したときは、それをあなたのコードとして扱います。「あなたの方法は長すぎます。

短いメソッドは、書きやすく、テストが簡単で、デバッグが簡単で、保守が簡単です。 10行以上のメソッドがない場合は、この問題に直面することはありません。

0

変数のスコープに関する最大の「パフォーマンス」の違いは、ガベージコレクションになります。変数をローカルに宣言すると、未使用の変数がGCによって早く収集される可能性があります。