JAvaコードの美しさ(11)---javaコードの最適化

4726 ワード

JAvaコードの最適化
自分で開発する時間が増えるにつれて、レブスの言うことをますます理解しています:コードを叩くのは詩を書くように美しいです.ある面接官がコードに潔癖なのかと私に聞いたことも理解できますか?
良いコードは詩のように見え、きれいな部屋のように見えて気持ちがいいです.
良いプロジェクトコードはこの3つの次元で分析できると思います.1) 2) 3)
コードに関する規範はずっと前からアリババのjava開発マニュアルがあり、中には非常に多くの規範があります.多すぎて、自分でも完全に覚えていないので、暇を見つけても時々ひっくり返します.
次に、パフォーマンスと可読性に関する習慣を書きます.後で何を考えて補充するか分かりません.
一、性能の考慮
1、注意しなければならない: 業務が確かに必要であれば、原因を説明したほうがいい.
2、できるだけ変数の繰り返し計算を減らす.
コンパイル最適化を行わない場合、ループではループ条件が繰り返し計算され、複雑な式を使用せずにループ条件値を変更しないと、プログラムがより速く実行されます.
for (int i = 0; i < list.size(); i++)
{...}
 //     :
for (int i = 0, length = list.size(); i < length; i++)
{...}

これでlist.size()は1回だけ呼び出され、パフォーマンスの消費量を削減します.
3、できるだけ怠惰なロードの策略を採用して、つまり必要な時にやっと作成します.
この習慣は、論理を書くとき、特にオブジェクトを作成するときに怠惰なロードを考慮する必要があるかどうかを育成する必要があります.
例:
A a = new A();
if (i == 1) 
{
list.add(a);
} 
//     :
if (i == 1) 
{
A a = new A();
list.add(a);
} 

4、文字列の累加.
1)ループ外:文字列接合はStringの+操作を直接使用することができ、StringBuilderでappendを行う必要はない.2)ループ内:ループ外でStringBuilderオブジェクトを宣言し、ループ内で手動appendを行うのが良い方法です.どのレイヤをループしてもStringBuilderオブジェクトは1つしかありません.
逆コンパイルされたバイトコードファイルは、ループのたびにnewがStringBuilderオブジェクトを1つ出力し、append操作を行い、最後にtoStringメソッドでStringオブジェクトを返し、メモリリソースの浪費をもたらすことを示します.
StringBuffer sb = new StringBuffer();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");
//               ,       :
String sb="a"+"b"+"c"+"d";

JDKの異なるバージョンによるString接合の最適化については、jdkの異なるバージョンによるString接合の最適化分析を参照してください.
5、splitの使用はできるだけ避ける.
splitは正規表現をサポートするため,効率が低い.
  String str1="a,b,c,d,,f,g"; 
  //      apache StringUtils.split(string,char)
  List list = Arrays.asList(StringUtils.split(str1, ","));
  //    guava  
  List list1=Splitter.on(",").splitToList(str1);

6、Stringbufferの容量を確定する
Stringbufferのコンストラクタは、デフォルトサイズ( 16)の文字配列を作成します.使用中、このサイズを超えるとメモリが再割り当てされ、より大きな配列が作成され、元の配列がコピーされ、古い配列が破棄されます.ほとんどの場合、Stringbufferを作成するときにサイズを指定することで、容量が足りないときに自動的に増加することを回避し、パフォーマンスを向上させることができます.
例:
 Stringbuffer buffer = new Stringbuffer(); // violation
 buffer.append ("hello");
//   : stringbuffer     。               
 Stringbuffer buffer = new Stringbuffer(max);
 buffer.append ("hello");

7、使用工具類Arrays.asList()配列を集合に変換する場合,その集合に関する修正手法を用いることはできない.
そのadd/remove/clearメソッドは、UnsupportedOperationException例外を放出します. :asListの戻りオブジェクトはArrays内部クラスであり,集合の修正方法は実現されていない.Arrays.asListはアダプタモードを体現し,インタフェースを変換するだけで,バックグラウンドのデータは配列である.
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
//     :list.add("c");      。
//     :str[0]= "gujin";   list.get(0)      。

8、配列要素を検索し、Arraysを使用することができる.asList(T[] array).contains(T obj)
二、可読性の考慮
1、else,if-elseをできるだけ少なく使うことをお勧めします
次のことが考えられます.
 if(condition){
   ...
 return obj; }
//     else        ;
:if()を使用しなければならない場合...else if()...else... :論理的に3層を超えるif-elseコードは、ガード文、またはステータスモードを使用して実現できます.
次に暇を見つけて、if-elseの3層以上のより良いソリューションブログを書きます.
2、if/else/for/while/do文では、1行のコードであってもカッコを使用する必要があります.
使用を避ける:if(condition)statements;
3、条件オペレータを使用して「if(cond)return;else return;構造.
//          
     if (isdone) {
         return 0;
     } else {
         return 10;
        }
//  
   return (isdone ? 0 : 10);

4、Objectのequalsメソッドはポインタ異常を空にしやすく、定数または値のあるオブジェクトを決定してequalsを呼び出す必要があります. : "test".equals(object); : object.equals("test"); :javaの使用を推奨.util.Objects(JDK 7に導入されたツールクラス)
5、任意の魔法値(すなわち、定義されていない定数)がコードに直接現れることは許されない.
String key="Id#taobao_"+tradeId;cache.put(key, value);

6、リバースオペレータ(!)プログラムの可読性を低下させるので、いつも使用しないでください.
 boolean method (boolean a, boolean b) {
        if (!a)
            return !a;
        else
            return !b;
    }

7、コメントしたコードは、簡単なコメントではなく、できるだけ説明に合わせなければならない.
コードが注釈される可能性は2つある:1) .2) .前者は注釈情報がなければ,注釈動機を知ることが困難である.後者は直接削除することを提案する(コード倉庫に履歴コードが保存されている).
8、特別な注釈マークは、マーク者とマーク時間を明記してください.
1) (TODO):(マーキング者,マーキング時間,[予定処理時間])は実現が必要であることを示しているが,現時点では実現されていない機能である.
2) (FIXME):(マーキング者,マーキング時間,[予定処理時間])あるコードを注釈にFIXMEでマーキングするのは誤りであり,かつ動作せず,適時に訂正する必要がある場合.
        ,            (  1)