ホームページ  >  記事  >  Java  >  Java 開発コードのパフォーマンス最適化の概要

Java 開発コードのパフォーマンス最適化の概要

黄舟
黄舟オリジナル
2017-02-06 13:11:471381ブラウズ

コードの最適化は役に立たないと思われる方もいるかもしれませんが、日々の開発プロセスの中で良い習慣を身につけていくように努めるべきだと思います。さて、私がよく使っている要約を共有しましょう。 codeコード最適化の目標codeコードサイズを減らす2システム全体の動作効率を向上させるコードの詳細を最適化する1ファイナルを指定しようとするクラスとメソッドの変更


最終的に変更されたクラスは派生されません。 Java コア API には、java.lang.String など、final を使用する例が多数あります。クラス全体に Final 修飾子を指定すると、クラスが継承されなくなります。また、メソッドに Final を指定すると、クラスが継承されなくなります。メソッドが継承されないように書き直されました。クラスを Final として指定すると、クラスのすべてのメソッドが Final になります。 Java コンパイラは、すべての最終メソッドをインライン化する機会を探します。インライン化は、Java の実行効率を向上させる上で重要な役割を果たします。詳細については、「Java ランタイムの最適化」を参照してください。これにより、パフォーマンスが平均 50% 向上します。


2 オブジェクトを再利用してみます


特に String オブジェクトを使用する場合、文字列接続が発生する場合は、代わりに StringBuilder/StringBuffer を使用する必要があります。 Java 仮想マシンはオブジェクトの生成に時間を費やすだけでなく、将来的にはこれらのオブジェクトのガベージ コレクションと処理にも時間を費やす必要があるため、オブジェクトの生成が多すぎるとプログラムのパフォーマンスに大きな影響を与えます。


3 可能な限りローカルオブジェクトを使用してください


メソッドの呼び出し時に渡されるパラメーターと呼び出し中に作成される一時変数は、高速化のためにスタックに保存されます。インスタンス変数など。それらはすべてヒープ内に作成されるため、速度が遅くなります。さらに、スタック内に作成された変数の内容はメソッドが終了すると消えるため、追加のガベージ コレクションは必要ありません。


4 適時にストリームを閉じます


Java プログラミング中、データベース接続と I/O ストリーム操作を実行するときは、使用後、リソースを解放するために適時にストリームを閉じてください。これらの大きなオブジェクトを操作するとシステムに多大なオーバーヘッドが発生するため、少し不注意をすると重大な結果につながります。


5 変数の繰り返し計算をできるだけ減らすようにしてください


概念を明確にし、メソッド内にステートメントが 1 つしかない場合でも、メソッドの呼び出しにはスタック フレームの作成などのコストがかかります。メソッド呼び出し時にシーンを保護する、メソッド呼び出しが完了するとシーンが復元されるなど。したがって、たとえば、次の操作:

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 例外を使用する場合は注意してください

例外はパフォーマンスに悪影響を及ぼします。例外をスローするには、まず新しいオブジェクトを作成する必要があります。Throwable インターフェイスのコンストラクターは、fillInStackTrace() という名前のローカル同期メソッドを呼び出し、スタックをチェックして呼び出しトレース情報を収集します。処理中に新しいオブジェクトが作成されるため、例外がスローされるたびに、Java 仮想マシンはコール スタックを調整する必要があります。例外はエラー処理のみに使用する必要があり、プログラム フローの制御には使用しないでください。

8 try…catch… をループ内で使用しないでください。絶対に必要な場合を除き、


の外側に配置する必要があります。理由もなくこれを書いた場合、リーダーが経験豊富で強迫性障害である限り、おそらくそのようなゴミコードを書いたと叱られるでしょう


9 追加するコンテンツの長さを見積もることができれば、ArrayList、LinkedLlist、StringBuilder、StringBuffer、HashMap、HashSet などの配列形式で実装された基礎となるコレクションとツール クラスの初期長を指定します

例として StringBuilder を取り上げます:

(1 ) StringBuilder( ) // デフォルトで16文字分のスペースを確保

(2) StringBuilder(int size) // デフォルトでsize文字分のスペースを確保

(3) StringBuilder(String str) // 16文字+strを確保。デフォルトの長さ () 文字スペース

はクラス (ここでは上記の StringBuilder だけを指すものではありません) を通じて初期化容量を設定でき、これによりパフォーマンスが大幅に向上します。たとえば、StringBuilder の場合、length は現在の StringBuilder が保持できる文字数を表します。 StringBuilder が最大容量に達すると、その容量が現在の容量の 2 倍に 2 を加えた値に増加するため、StringBuilder は最大容量に達するたびに、新しい文字配列を作成し、古い文字をその配列で置き換える必要があります。配列は新しい文字配列にコピーされます。これは非常にパフォーマンスを重視する操作です。想像してみてください。長さを指定せずに文字配列に約 5000 文字が格納されると推定でき、5000 の 2 の最も近い累乗は 4096 で、展開ごとに 2 が加算され、次のようになります。

(1) in 4096 を基準にすると、8194 個の文字配列を申請することになり、最初に 5000 個の文字配列を指定できれば、2 倍以上のスペースを節約できます

( 2) 元の 4096 文字を新しい文字配列にコピーします

这样,既浪费内存空间又降低代码运行效率。所以,给底层以数组实现的集合、工具类设置一个合理的初始化容量是错不了的,这会带来立竿见影的效果。但是,注意,像HashMap这种是以数组+链表实现的集合,别把初始大小和你估计的大小设置得一样,因为一个table上只连接一个对象的可能性几乎为0。初始大小建议设置为2的N次幂,如果能估计到有2000个元素,设置成new  HashMap(128)、new HashMap(256)都可以。


10 当复制大量数据时,使用 System.arraycopy() 命令


11 乘法和除法使用移位操作


例如:

for (val = 0; val < 100000; val += 5)
{
a = val * 8;
b = val / 2;
}

用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的,因此建议修改为:

for (val = 0; val < 100000; val += 5)
{
a = val << 3;
b = val >> 1;
}

移位操作虽然快,但是可能会使代码不太好理解,因此最好加上相应的注释。

12 循环内不要不断创建对象引用


例如:

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

这种做法会导致内存中有count份Object对象引用存在,count很大的话,就耗费内存了,建议为改为:Object obj = null;for (int i = 0; i <= count; i++) { obj = new Object(); }
这样的话,内存中只有一份Object对象引用,每次new Object()的时候,Object对象引用指向不同的Object罢了,但是内存中只有一份,这样就大大节省了内存空间了。

13基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组大小时才使用ArrayList


14尽量使用HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销


15 不要将数组声明为 public static final


因为这毫无意义,这样只是定义了引用为 static final ,数组的内容还是可以随意改变的,将数组声明为 public 更是一个安全漏洞,这意味着这个数组可以被外部类所改变


16 尽量在合适的场合使用单例


使用单例可以减轻加载的负担、缩短加载的时间、提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:


(1)控制资源的使用,通过线程同步来控制资源的并发访问

(2)控制实例的产生,以达到节约资源的目的

(3)控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信


17 尽量避免随意使用静态变量


要知道,当某个对象被定义为 static 的变量所引用,那么 gc 通常是不会回收这个对象所占有的堆内存的,如:

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

以上就是Java开发代码性能优化总结的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。