web-dev-qa-db-ja.com

while-else-loop

もちろん、これはJava(to-date)の不可能なステートメントですが、理想的には多くの反復の中心にあるように実装したいと思います。たとえば、最初の複数回はArrayListを作成しているときに、650,000回以上呼び出しています。残念ながら、実際のコードにはsetループ内にelseがありません。 addコマンドとsetコマンドの両方と時間の浪費になります。

その後、データが既に作成されているためセットを実行するだけの別のループにもありますが、これは他の多くのものとマルチネストされているため、時間がかかります。

ArrayList<Integer>  dataColLinker = new Java.util.ArrayList<Integer>();
...
...
public void setLinkerAt( int value, int rowIndex) {
    ...
    while(rowIndex >= dataColLinker.size()) {
        dataColLinker.add(value);
    } else {
        dataColLinker.set(rowIndex, value);
    }

アイデアや理論はありますか? ifステートメントやArrayListコマンドなどに関しては、Java)の速度がわかりません

10
xchiltonx

何か不足していますか?

この架空のコードは

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
} else {
    dataColLinker.set(rowIndex, value);
}

これと同じことを意味する?

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
}
dataColLinker.set(rowIndex, value);

それともこれ?

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}

(後者はより理にかなっています...私は推測します)。いずれにせよ、ループを書き換えて、ループ内で「else test」が繰り返されないようにすることができることは明らかです...先ほど説明しました。


FWIW、これはおそらく最適化が時期尚早の場合です。つまり、おそらく最適化する必要のないコードの最適化に時間を浪費していることになります。

  • ご存じのとおり、JITコンパイラのオプティマイザーは既にコードを移動しているため、「その他」の部分はループ内に存在しません。

  • たとえそうでなかったとしても、最適化しようとしている特定のものが重大なボトルネックにならない可能性があります... 600,000回実行されたとしてもです。

私のアドバイスは、今のところこの問題を忘れることです。プログラムを機能させます。動作しているときに、十分に高速で実行されるかどうかを判断します。プロファイリングを行わない場合は、プロファイラーの出力を使用して、最適化に時間をかける価値がある場所を決定します。

20
Stephen C

しばらくカプセル化されている理由がわかりません...

使用する

//Use the appropriate start and end...
for(int rowIndex = 0, e = 65536; i < e; ++i){        
    if(rowIndex >= dataColLinker.size()) {
         dataColLinker.add(value);
     } else {
        dataColLinker.set(rowIndex, value);
     }    
}
3
Jay
boolean entered = false, last;
while (( entered |= last = ( condition ) )) {
        // Do while
} if ( !entered ) {
        // Else
}

どういたしまして。

1
momomo

「set」ステートメントをラップして「set if not set」を意味し、whileループの上にそのまま置きます。

あなたは正しいです、言語はあなたがまさにその構文で探しているものを提供しませんが、それはあなたが提案している構文を必要としないように私がちょうど提案したようなプログラミングパラダイムがあるからです。

1
djechlin

Pythonから来て、これを同じものとして受け入れると仮定すると:

def setLinkerAt(value, rowIndex):
    isEnough = lambda i: return i < dataColLinker.count()
    while (not isEnough(rowIndex)):
        dataColLinker.append(value)
    else:
        dataColLinker[rowIndex] = value 

私が思いついた最も類似したものは:

public void setLinkerAt( int value, int rowIndex) {
    isEnough = (i) -> { return i < dataColLine.size; }
    if(isEnough()){
        dataColLinker.set(rowIndex, value);
    }
    else while(!isEnough(rowInex)) {
        dataColLinker.add(value);
    }

ロジックとリバースロジックの必要性に注意してください。これが優れた解決策(ロジックの複製)であるかどうかはわかりませんが、必要以上にロジックを実行しないという同じ行為を維持しながら、ブレースレスelseが私が考えることができる最も近い構文です。

0
Jefferey Cave

このwhile elseステートメントは、条件がfalseの場合にのみelseコードを実行する必要があります。つまり、常に実行されます。ただし、問題があります。whileループ内でbreakキーワードを使用すると、elseステートメントは実行されません。

条件を満たすコードは次のとおりです。

boolean entered = false;
while (condition) {
   entered = true; // Set it to true stright away
   // While loop code


   // If you want to break out of this loop
   if (condition) {
      entered = false;
      break;
   }
} if (!entered) {
   // else code
}
0
Kamil B

Javaにはこの制御構造がありません。
ただし、他の言語でも同様です。
たとえば、Pythonには while-else 構造があります。

Javaの場合、すでに示したように、この動作を模倣できます。

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}
0
Trevor Hickey