2015-12-24 6 views
11

私は少しの研究をしましたが、私は主にC++の回答を見ています。私が一番近かったのはthisです。私もthis pageを見ましたが、実際に何も説明していません。Java - インライン化コードには利点がありますか?

2番目のコードを使用すると利点はありますか?パフォーマンスに著しい違いがありますか?メモリはどうですか?何度も繰り返していたら?

今私はこの機能を持っています。単純な例は次のようになり

private static Bitmap resize(Bitmap image, int maxWidth) { 
    return Bitmap.createScaledBitmap(image, maxWidth, Math.round(image.getHeight() * (float) maxWidth/image.getWidth()), true); 
} 

for(;;) { 
    String foo = "hello"; 
    Console.print(foo + "world"); 
} 

対私は、コードのこの第二のスニペットを持って、今

private static Bitmap resize(Bitmap image, int maxWidth) { 
    float widthReducePercentage = ((float) maxWidth/image.getWidth()); 
    int scaledHeight = Math.round(image.getHeight() * widthReducePercentage); 

    return Bitmap.createScaledBitmap(image, maxWidth, scaledHeight, true); 
} 

:私はこれの利点は、コードの読みやすあると確信しています

for(;;) { 
    Console.print("hello" + "world"); 
} 
+0

私はコンパイラがとにかく離れて最適化すると思うので、あなたのテストペアの例は同様に動作するかもしれません。どのような場合でも、インライン化によりコードを読みやすくすることができます。 –

+2

あなたが与えた例については、パフォーマンスに全く違いはありません。このような「最適化」を気にしないでください。何が最善のものであれば何でもしてください。 –

+0

@LouisWasserman Roger that – pandalion98

答えて

9

最初:これは「インライン化」が意味するものではありません。参照:What is inlining?

第2:いいえ、パフォーマンスには大きな違いはありません。どちらのコード例でも、コンパイルされたコードは両方のバージョンで同じになる可能性があります。

+2

Javaバイトコードは、ローカル変数が削除されていない(デバッグに使用できる)ため、異なる場合があります。 JITとおそらくDalvikコンパイラがそれらを削除します。 – chrylis

+0

この回答を投稿した後、私はLIProfに似た簡単な実験を行いました。コンパイルされたファイルは実際には異なっていました。私は '-g:none'フラグを使いましたが、デバッグシンボルがあってはいけません。だから私は思ったより少し複雑だと思う。 –

3

両方ともサムe。前者は事態を後者よりも明確にします。

以下のような、1ライナーを有効にするような状況があります。

public boolean isEmpty() { 
    return getCount() != 0; 
} 

あなたはそれを読みやすくしたい場合は、それは方程式に来るとき、特に、variableのために行きます。 1つのライナーはそれを単純で短くしますが、短く単純なロジックには良いです。

これは私の個人的な意見です。

4

2つの単純なクラスTest1Test2を定義し、それらをコンパイルしました。私の驚いたことに

public class Test1{ 
    public String f(){ 
     String s = "Hello"; 
     String t = "There"; 
     return s + t; 
    } 
} 

public class Test2{ 
    public String f(){ 
     return "Hello" + "There"; 
    } 
} 

、.classファイルは同じサイズではありません。

-rw-r--r-- 1 csckzp staff 426 Dec 23 19:43 Test1.class 
-rw-r--r-- 1 csckzp staff 268 Dec 23 19:43 Test2.class 

おそらく、象徴的な情報の一部がコードとともに保存されるので、私は驚いてはいけません。 .classファイルをオンラインデコンパイラで実行しました。 。Test1はかなりそれがで入力された道を再建されたTest2、一方で、この方法を逆コンパイル:

public class Test2 { 
    public String f() { 
     return "HelloThere"; 
    } 
} 

コンパイラの最適化が明確にここに表示されます。おそらく、非コンパクトコードのためにJavaには小さなペナルティがあります。

+1

私は驚いていません。バイトコードコンパイラは*非常に*最小限の最適化を行います。それらの等価性は実行時に証明されます。 – Veedrac

+1

コンパイラはコンパイル時に結果を判別できる操作を排除しようとします。だから、 "Hello" + "There"が "HelloThere"に変わったのです。 –

1

ローカル変数はバイトコードへの変換に耐えますが、コンパイル時には生き残ることはほとんどありません。さらに、ローカル変数が存在していても、ローカル変数を格納または取得するよりもビットマップをリスケーリングするほうが高価なため、そのメソッドのパフォーマンスに大きな影響はありません。

文字列連結に関する2番目の例では、ローカル変数が存在するため定数文字列の連結のコンパイル時評価が禁止されるため、この規則に対する小さな例外が強調表示されています。しかし、プログラムの実行時に重大な影響を及ぼす可能性は非常に低いです。定数文字列を頻繁に連結しない可能性があるからです。

一般的に言えば、ランタイムパフォーマンスにローカル変数をインライン化することの影響は、めったに測定できません。したがって、コードを読みやすくして理由を簡単にすることで、プログラマーのパフォーマンスを最適化するためには、はるかに時間がかかります。

関連する問題