蘇小さな暖かいJavaのパフォーマンスの最適化

コードの最適化、非常に重要な問題。一部の人々は、変更することは何も、変化とそのためのコードの効率に影響を与えるものを変更していないが存在しない、いくつかの小さな場所を無駄に感じるかもしれませんか?問題は、それがエビが有用食べる、内部のクジラのように、海のように、私が考える何ですか?うんざりしたクジラ役に立たない、しかし、後に複数のエビを食べます。

ないBUGプロジェクトはできるだけ早くラインに焦点を当てた場合は、コードの最適化は、同じである、そして時間はコードの詳細は審議ではないとすることができ、発生する可能性がある。しかし、コードを開発し、維持するのに十分な時間がある場合は、この時点では、各を考慮する必要がありますあなたは詳細を最適化し、そして絶対的にアップグレードされたコードの効率化のために蓄積された一つの小さな最適化のポイントずつすることができます。

速攻は速攻で廃棄物を作る到達するために無駄になります!

コードの最適化の目的は、以下のとおりです。

  • コードサイズ縮小
  • コード実行の効率を向上させます

コードの最適化の詳細

1、final修飾子を使用するようにしてください

最終的な修飾子クラスは、JavaコアAPIに導出されていないと、例はjava.lang.Stringのために、クラス全体が最終であり、最終的なアプリケーションの多くの例があります。クラスの最後の修飾子を指定したクラスを継承することはできませんことができます、final修飾子は、メソッドの方法を作るために書き換えることはできません指定します。クラス決勝を開発した場合は、すべてのメソッドのクラスは最終的なものです。Javaコンパイラは、50%の平均でパフォーマンスを向上させることができ、すべてのメソッドで、最終的な内の機会については、Javaの運用効率を向上させるためのインライン大きな役割を見ていきます。

2、オブジェクトを再利用しよう

特定の用途文字列オブジェクトではなく、文字列のStringBuilderまたはStringBufferの接続のが使用されるべきです。Java仮想マシンがオブジェクトを生成するのには時間がかかるだけでなくので、将来的には、プログラムのパフォーマンスに大きな影響をもたらすでしょう、したがって、ガベージコレクションおよび処分のため、これらのオブジェクトに時間を費やすあまりにも多くのオブジェクトを生成する必要があるかもしれません。

3、ローカル変数を使用するようにしてください

スタックに保存されている呼び出しで、メソッドのパラメータを呼び出すときに渡され、一時的な変数が作成され、より速く、など静的変数、インスタンス変数、などの他の変数は、ゆっくりと、ヒープ上に作成されます。また、操作の方法で作成したスタック変数は、コンテンツがなくなって、追加のガベージコレクションを完了していません。

図4に示すように、流れを閉じます

IOストリーム動作は、使用後に、速やかにリソースを解放するためにシャットダウンしたときに、Javaプログラミング、データベース接続は、注意してください。そのためこれらの大きなオブジェクトのオーバーヘッドが生じた大きなアクションで、わずかなミスが重大な結果につながります。

変数のダブルカウントを最小限にするために5、

明確なコンセプト、メソッド呼び出しは、方法は一つだけの文章であっても、方法、メソッドを呼び出し終え復旧サイトを呼び出すときに、サイトを保護するために、スタックフレームの作成など、消費されます。したがって、たとえば、次の操作:

for(int i=0;i<list.size;i++){}

推奨代替品:

for(int i=0,int length=list.size;i<length;i++){}

このように、はlist.size時間の多くは、それが消費の多くを軽減します。

必要なときにのみ作成され、可能な限り6、遅延ロード戦略、

例えば:

String str = "aaa";if (i == 1){list.add(str);}

推奨代替品:

if (i == 1){String str = "aaa";list.add(str);}

図7に示すように、異常な注意

パフォーマンスへの異常な有害。例外は、新しいオブジェクトを作成、収集情報のコールトラッキングにスタックをチェックするために地元の同期方法にfillInStackTraceと呼ばれたThrowableインタフェースのコンストラクタ、にfillInStackTraceメソッドを呼び出すために最初にスローされます。新しいオブジェクトがプロセスで作成されているため、限りスローされる例外があるとして、Java仮想マシンは、コールスタックを調整する必要があります。例外は唯一のエラー処理のために使用することができ、プログラムの流れを制御するために使用すべきではありません。

8.ループでtrycatch使用しないでください、それが最も外側に配置する必要があります

最後の場合を除きます。理由もなくそう書かれた場合は、限り、あなたはほとんどのシニアリーダーシップ、少し強迫性障害があるとして、おそらくあなたは、なぜ、ごみにこのコードを書く呪います。

図9は、初期の長さを指定し、底層がアレイ実装ツールとして設定されている追加するコンテンツの長さを推定しようとすることができ

そのようなStringBuilderの例に、等のArrayList、LinkedLlist、のStringBuilder、StringBufferの、HashMapの、HashSetの、など。

①のStringBuilder //デフォルトのスペースは、16個の文字を割り当てられました

②のStringBuilder(int型のサイズ)//デフォルト・スペースの割り当てサイズの文字

③StringBuider(String str)文字// 16文字+ st.lengthの文字スペースのデフォルトの割り当て

初期容量を設定すると、パフォーマンスが大幅に向上させることができます。例えば、StringBuilderのため、長さは保持することができ、現在のStringBuilder内の文字の数を示します。StringBuilderのが最大容量に達したときのStringBuilderだけその最大容量に達するたびに、それ自体が、2プラス2倍の電流容量を増加しますので、それは新しい文字配列し、古いキャラクターを作成する必要があります非常に時間のかかる操作のパフォーマンスである - 文字配列の新しい配列にコピーされたコンテンツ。あなたは、長さを指定せずに5000文字程度の店に2 5000 4096の最も近いパワーを文字配列を推定することができるならば、想像し、すべての拡張二重2 2、そして:

①4096、8194に基づいて、その後、文字配列のサイズを適用し、開始が2倍以上のスペースを節約し、文字配列5000のサイズを指定することができれば、12290文字配列のサイズを提出したのと同等にまで追加。

②文字の新しい配列にコピーし、元の4096個の文字が行きます。

このように、メモリ空間の浪費とコードの効率を低下させます。合理的な初期容量を設定するためのツールのセットを達成するために、基になる配列が間違っていないとそう、それはすぐに結果をもたらすでしょう。ただし、そのようなセットの配列のハッシュマップ+リンクリストの実装として、唯一の理由は、接続テーブル上のオブジェクトの可能性を、同じサイズの初期推定と、あなたのセットのサイズを行うには、ほぼゼロです。2,000の要素が新しいハッシュマップ(128)、新しいハッシュマップ(256)を使用してもよい提供があると推定される場合、2の初期サイズN番目のパワーを設定することを推奨。

コマンドを使用して、大量のデータをコピーする10、System.arraycopyの

乗算および除算を使用して11、シフト演算

例えば:

int a = 0;
int b = 0;
for (int i = 0; i < 1000000000; i++){
   a = i * 8;
   b = i / 2;
}

コンピュータの底面には、動作位置が最も便利であるので、シフト操作が大幅にパフォーマンスを向上させることができ、最速は、それは次のように改正提案されています。

int a1 = 0;
int b1 = 0;
for (int i = 0; i < 1000000000; i++){
    a1 = i << 3;
    b1 = i >> 1;
}

シフト動作が速いかもしれないが、コードを作るあまりよく理解かもしれないが、それは適切なコメントを追加することをお勧めします。 

少しうるさいを感じ、どのように多くのサイクルがすべて、唯一悪化さ2ミリ秒!

12、内側ループは、オブジェクト参照を作成し続けません

例えば:

for (int i = 1; i <= count; i++){
    Object obj = new Object;
}

このような行為は、コピーObjectオブジェクトの参照カウントを持っているメモリにつながる多くを数えることができ、それはメモリのコストがあり、読むことをお勧めします。

Object obj = null;
for (int i = 0; i <= count; i++) {
    obj = new Object;
}

この場合には、一つだけのメモリオブジェクトのオブジェクト参照、ときそれぞれの新しいオブジェクト、オブジェクトオブジェクトオブジェクトの基準点何も異なるが、唯一つのメモリ、大幅なセーブメモリ空間アップ。

唯一の13は、効率性と型チェックの考慮事項に基づいて、配列は、可能な限り使用されなければならない、我々はArrayListのを使って配列のサイズを決定することはできません

図14は、使用のハッシュマップを作るために、ArrayListの、StringBuilderのは、スレッドのセキュリティニーズがない限り、それによる性能オーバーヘッドにつながる同期メカニズムを使用するハッシュテーブル、ベクター、StringBufferの、後者の3つを使用することが賢明ではありません。

15、配列について話していないが、公共の静的ファイナルとして宣言しました

図16は、適切な場合には、シングルモードの実施形態を利用すること

、負荷の負担を軽減負荷までの時間を短縮し、ローディングの効率を向上させることができるシングルトンパターンを使用して、すべての場所は簡単な言葉で、Singletonパターンは、主に以下の三つの側面に適用され、単一のケースのモデルに適しています。

①資源、スレッドによるリソースの同期制御の同時アクセスの使用を制御

②資源を節約するために、コントロールのインスタンスを生成します

③制御データは複数のプロセスまたはスレッドの間で無関係な通信を実現するように、直接的に確立に関連しない条件下で、共有

17、静的変数を使用して回避しよう

あなたがオブジェクトをstaticとして定義されている場合、知っている、そしてGCは、通常は回復しない。このヒープメモリは、オブジェクトによって占有しました

public class A{
    private static B b = new B;
}

プログラムが終了するまで、同じクラスAのライフサイクルのこの静的変数B、クラスAの永久メモリのオブジェクトのアンインストールされない場合、基準点Bで。

18は、タイムリーな除去セッションはもはや必要ではありません

セッションはもはやアクティブでクリアしないために、多くのサーバーは、通常30分、既定のタイムアウト時間を持つことになります。より多くの会話を維持する場合は、アプリケーションサーバーの必要性、メモリ不足、オペレーティングシステムは、ディスクへのデータの一部を譲渡する場合、アプリケーションサーバーは、ディスクへの非アクティブなセッションをダンプして、さらにメモリ例外を投げすることができます。セッションをディスクにダンプする場合は、最初に直列化されなければならない、大規模なクラスタでは、オブジェクトのシリアライズ価格が非常に高いです。セッションが不要になったときにそのため、あなたは速やかにhttpseesion呼び出していないセッションの無効化の方法をクリアする必要があります。

19、インターフェースのセットがあなたの代わりに、foreachループのループのための最も一般的に使用する必要があり、そのようなArrayListのようランダム・を達成するために

彼らは高速なランダムアクセスをサポートすることを示しているRandomAccessインタフェースを達成するため、このインタフェースの主な目的は、一般的なアルゴリズムが良好な性能を提供する際に、ランダムまたはシーケンシャルアクセスリストに適用するために、自分の行動を変えることを可能にすることです。実際の経験が示すランダム・インターフェース・クラス・インスタンス、もし今度は通常の使用foreachループのためのより高いサイクル効率を使用してランダムアクセス、シーケンシャルアクセスであれば、より効率的なイテレータの使用。同様に、コードは、次を決定するために使用することができます。

if (list instanceof RandomAccess){ 
    for (int i = 0; i < list.size; i++){}
}else{
    Iterator<?> iterator = list.iterable; while (iterator.hasNext){iterator.next}
}

基本的な実装のforeachのは、イテレータです。

代わりに、同期コードブロックを使用して同期化方法の20、

21、定数は、静的最終として宣言され、大文字で指定されています

コンパイル時にコンテンツが動作中に一定の計算値の生成を回避するために、一定のプールに入れることができるように。また、大文字の名前の定数名も容易変数と定数とを区別することができます。

22は、使用していないいくつかのオブジェクトを作成していない、いくつかのクラスをインポートしていない使用しないでください

23、プログラムは、リフレクションを使用しないように実行されています

Javaのリフレクションは、非効率的な非常に強力な、強力な手段によって提供されます。メソッドInvokeメソッド特に、特にプログラムにおける反射の頻繁な使用が実行されている、お勧めできません、実際に必要な示唆的なアプローチがある場合には、これらのクラスは、プロジェクトが反射によって起動時にロードする必要が反映されていますオブジェクトをインスタンス化し、メモリ内に配置 - プロジェクトが開始された時刻に関係なく、唯一の懸念スピードの相互作用を。

データベース接続プーリングとスレッドプールを使用して24、

前者は頻繁に、開口部を回避し、接続を閉じることができ、後者は頻繁に作成および破棄のスレッドを回避することができ

25、バッファ入力と出力を使用してIO操作ストリーム

緩衝入出力ストリーム、大幅IOの効率を向上させることができる、すなわちBufferedReaderの、BufferedWriterの、BufferedInputStreamを、なBufferedOutputStream、。

26、挿入の順序とは、ArrayListのシーンでより多くのランダムアクセスであり、LinkedListのを使用して要素の削除よりシーンを介在します

27は、パブリックプロセスがあまりにも多くのパラメータを持つことはできません。

28、文字列変数と文字列定数は、時定数文字列EDITORIALに等しいです

主にヌル・ポインター例外を避けるためにそれを行います。

29、Javaでそれを知っていれば(I == 1)としてください(1 == i)がそこには違いはありませんが、あれば前者がと話すの読書習慣、

30、配列toStringメソッドを使用していません

図31は、基礎となるデータに必須の遷移が範囲外の入力ダウン行いません

32、一般的なデータ収集クラスは、オフタイムリー削除する必要があります使用されていません

コレクションは(つまり、プロパティの内側の方法ではありません)公開されている場合、基準点は、それらに常にあるので、その内の要素のセットが自動的に、解放されません。データの一部がそれらを削除するのではなく公共の収集の内側を使用していないのであれば、それは、システムがメモリリークの問題があるので、こと、公共の収集が増加している原因となります。

図33は、文字列への塩基型に、最速のtoStringは、最も遅い「」String.valueOf、データ+に従っ

我々はtoStringメソッドの使用を優先して、時間の文字列への基本的なデータ型の後に遭遇したので。なぜとしては、それは簡単です:

①String.valueOfメソッドを持つInteger.toStringメソッド呼び出しの基礎となるが、裁判官を呼び出す前に短くなります

②持つInteger.toStringメソッドは直接呼び出し、言っているわけではありません

③私は+「」底のStringBuilderは、縫合することにより、第1追記方法を使用して実装、toStringメソッドは、文字列を受け取り、次いで

三つのコントラストダウン、明らかに最速②、①の後、③最も遅いです

トラバースマップに最も効率的な方法を使用して34、

推奨され35、リソースを閉じる()が別々に操作しました

平均値は、例えば、私はコードの、このような作品を持っています:

try{
    XXX.close;
    YYY.close;
}catch (Exception e){
...
}

変更案は以下のとおりです。

try{ 
    XXX.close; 
}catch (Exception e) {
 ... 
}
try{ 
    YYY.close; 
}catch (Exception e) {
 ... 
}

いくつかのトラブルが、彼は、リソースリークを避けることができました。例外をスローXXX.close場合には、コードを変更しない場合、私は、考えて、その後、カテーテル検査でブロックを入力し、YYY.closeが実行されない、このリソースが回復されることはありませんYYYは、そう、で占められてきましたより1つのコードよりも、リソースハンドルリークが発生することが可能です。しかし、文言の後にどのような場合にはXXXとYYY近いうちになることが、上記、性を保証に変更されました。

公開された110元の記事 ウォンの賞賛8 ビュー6928

おすすめ

転載: blog.csdn.net/guorui_java/article/details/104107390