るループは、より良い実績を教えてください。なぜですか?
-
02-07-2019 - |
質問
String s = "";
for(i=0;i<....){
s = some Assignment;
}
または
for(i=0;i<..){
String s = some Assignment;
}
んを利用する必要が's'また外側のループます。最初のオプションはおそらくりの新しい文字列が初期化されません。第二はこの範囲の変数のループそのものです。
編集:応Milhousの答えです。いい意味を割り当て文字列定数内のループができるのではないか。いいえ、ここで一部の譲渡すことの変化値からのリストが反復す。
また、質問なんで気になメモリ管理.だけを知りたい気がします。
解決
限られた範囲内で
を使用オプション:
for ( ... ) {
String s = ...;
}
範囲なの性能に影響を及ぼす
場合分解-コードの作成から、JDKの javap
ツール)と、ループを統を同じJVMに指示しました。ることにも注意 ブライアンR.ボンディの "オプション#3"をオプション#1.何も追加で追加または削除が行われたときにスタック使用時の強化な範囲で、同じデータが使用されているスタックの両方である。
を避ける早期の初期化
の差は、両案件内では、最初の例では、変数 s
必要以上に初期化されます。これは別の場所からの変数宣言です。この追加につ無駄の指示への負荷の文字列定数や店舗でスタックフレームのスロット).良い静的解析ツールに警告を表示することが決してない読みの値を指定 s
, もJITコンパイラのだろうelideで行います。
きの修正にこのことにより、空の宣言(= String s;
ものであると考えている悪い練習が効果について検討する。
が偽のような値 null
付けされた変数は、単なるハッシュコンパイラエラーが発生する変数を読み取ることなく初期化されます。このエラーで取れたてのヒントとなるのは可変範囲は大きすぎると、とされているものであることを宣言したものでは受取のための有効な値です。空の宣言力を考慮毎にコードパス思を無視するこの貴重な警告を配架空の値です。
保全スタックのスロット
して、JVMの指示は両者とも同じであるが、微妙な効果ることを最適にし、JVMレベルの利用に限定的な範囲で可能です。これは、"局所変数テーブル"の方法。を考えれば、一体どうなることは複数のループを宣言した変数を必要以上に大きな範囲:
void x(String[] strings, Integer[] integers) {
String s;
for (int i = 0; i < strings.length; ++i) {
s = strings[0];
...
}
Integer n;
for (int i = 0; i < integers.length; ++i) {
n = integers[i];
...
}
}
の変数 s
や n
が宣言された内部のそれぞれのループからない、コンパイラを使用して"スロット"のスタックフレーム。が宣言された内側のループは、コンパイラの再利用することも可能で、同じスロットのスタックフレームを小さくなります。
何をどの
しかし、これらの問題が軽微です。良いJITコンパイラを見ることはできませんの初期値で無駄を割り当て、および最適化の割り当てます。省スロットではありませんかいうものではありませんを願います。
重要なのは、コード読み取りやすいの維持を持っているので、その意味では、限定的な範囲では明らかです。の範囲の変数は、すでに把握されそれ以外の用途には使用い、どのような影響をに変更をコードする道があります。
他のヒント
に 理論, では、廃棄物の資源を宣言する文字列の内側のループを実行します。に 実践, しかし、両方のスニペットをご提示までをコンパイルを同じコード宣言"社外のループ).
そのため、コンパイラはサイトの著作権は、弊社の最適化、ありません。
一般らばらになってしまったと思うのでの範囲は's'変数には限定されます。特典:
- このプログラマーなどの心配は's'の使用を再度かの機能
- このようにコンパイラでの範囲の変動が小さいので、その可能性のあるい解析と最適化
- これはより良い未来の読者がいかに's'変数が宣言された外側のループだけを利用したことのない後
したい場合の高速化のためのループに好の宣言に最大変数にカウンターではないことを繰り返しルックアップのためのcondidtion必要となる
の代わりに
for (int i = 0; i < array.length; i++) {
Object next = array[i];
}
ります。
for (int i = 0, max = array.lenth; i < max; i++) {
Object next = array[i];
}
その他のものとして述べさせていただき、かつセントを参照ericksons)
Greetz,GHad
追加するビットを@にエステバ新家の回答, なが要求されるため、新しい文字列の各時間のループとしては、返却値の型に"byte[]"を指定 some Assignment
表現).その文字列が必要なゴミを回収する。
そうすることを義務付けられているが、ようと思って追加のビット 少し します。
にのってながら閲覧のJavaソースコードする方法のような文字列になります。contentEquals(複製)する冗長ローカル変数を単なるコピーのクラス変数です。この言があったどこかで見たような気がすることが示唆されローカル変数にアクセスがよりアクセスのクラス変数です。
この場合"v1"と"v2"一見不必要がなく簡単にコードが追加され性能の向上を図ります。
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
if (count != sb.length())
return false;
char v1[] = value;
char v2[] = sb.getValue();
int i = offset;
int j = 0;
int n = count;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
}
return true;
}
そしてさらなる仕様の問題です。
の
s = some Assignment;
が指定されていないとしてどのような課題ことです。場合には
s = "" + i + "";
その後新しいスティングニーズへの割り当てられてしまいます。
の場合には
s = some Constant;
sは単に点を定数のメモリ位置は、このように、最初のバージョンがメモリ効率的です。
うっか心配に最適化のためのループのために解釈されlangぁ.
私は複数のスレッド(50+)を見つけることは非常に効果的な取扱いにつきましてゴーストのスレッド問題となりプロセスを正しく....がん間違っているのは、みなさん、そしてなぜ私は思っていたが、あるきっかけで
Process one;
BufferedInputStream two;
try{
one = Runtime.getRuntime().exec(command);
two = new BufferedInputStream(one.getInputStream());
}
}catch(e){
e.printstacktrace
}
finally{
//null to ensure they are erased
one = null;
two = null;
//nudge the gc
System.gc();
}