1

for ループ内で Mongo DB クエリを実行しています。ループには 1500 回の反復が含まれています。とにかく、50回の反復の後、DBに時間を与えたいということはありますかThread.currentThread().sleep(200);

では、50 回ごとにしばらく停止する方法を教えてください。

for (int i = 0; i < n; i++){
    // ????
}
4

8 に答える 8

11

これにはモジュロを使用します

if( i % 50 == 0 ){
    Thread.sleep(200);
}
于 2012-12-05T11:00:54.110 に答える
4

一部の CPU を使用できるモジュロを使用する代わりに、ネストされたループを使用します。

for (int j = 0; j < n; j += m) {
    // before every m
    for(int i = j; i < j + m && i < n; i++) {
        // inner
    }
    // after every m
}

これは%よりも速いでしょうか?

static int counter, counter2;

public static long testOneModLoop(int n, int m) {
    long start = System.nanoTime();
    for (int i = 0; i < n; i++) {
        counter++;
        if (i % m == m - 1)
            counter2++;
    }
    return System.nanoTime() - start;
}

public static long testTwoLoops(int n, int m) {
    long start = System.nanoTime();
    for (int j = 0; j < n; j += m) {
        for (int i = j; i < j + m && i < n; i++) {
            counter++;
        }
        counter2++;
    }
    return System.nanoTime() - start;
}

public static void main(String... args) {
    for (int i = 0; i < 5; i++) {
        int runs = 10 * 1000 * 1000;
        double time1 = (double) testOneModLoop(runs, 50) / runs;
        double time2 = (double) testTwoLoops(runs, 50) / runs;
        System.out.printf("Avg time for 1 loop: %.2f ns and 2 loops: %.2f ns%n",
                time1, time2);
    }
}

版画

Avg time for 1 loop: 6.09 ns and 2 loops: 0.78 ns
Avg time for 1 loop: 3.75 ns and 2 loops: 0.22 ns
Avg time for 1 loop: 3.67 ns and 2 loops: 0.19 ns
Avg time for 1 loop: 3.72 ns and 2 loops: 0.19 ns
Avg time for 1 loop: 3.67 ns and 2 loops: 0.19 ns
于 2012-12-05T11:07:31.837 に答える
3

Peter Lawreyの回答に基づいて、すべてを1つのループに入れて、最初の反復でモジュロとスリープの両方を回避できます。

for (int i = 0, j = 0; i < n; ++i, ++j) { //we increment both i and j
     if (j == 50) {                       // reset auxilliary counter and go to sleep
          j = 0;                       
          Thread.sleep(100);
     }
}

編集

ちなみに、パフォーマンスが心配な場合は、64 回 (または別の 2 のべき乗) の反復ごとに停止して、次の事実を使用できます。

n % k == n & (k - 1) when k is a power of two and n > 0

このようにして、比較的高価なモジュロ操作を安価なビット単位に変更できます&。プログラミングで 2 の累乗のサイズを使用することは、一般的には良い考えです。

于 2012-12-05T11:20:00.623 に答える
3

次のようにモジュロを使用します。

for (int i = 0; i < n; i++){
      if( i%50 == 0){
         Thead.sleep(200);
      }
}

i これは、50 の倍数になるたびに真になります。

于 2012-12-05T11:00:55.910 に答える
2

これは一般的に良い考えではないと思いますが、あなたが尋ねたとき:

if (i % 50 == 0 && i!=0) {
// Do something
}
于 2012-12-05T11:02:00.897 に答える
1

すべての「n」クエリをスリープ状態にする方法に関係なく、これが本当にあなたがやりたいことなのかどうか疑問に思います。IDのリストを取得して各ドキュメントのデータベースにクエリを実行する代わりに、より適切なクエリをデータベースに送信し、おそらく最適化されたクエリAPIを使用して情報を検索/返すことはできません。

于 2012-12-05T11:03:19.970 に答える
0
for (int i = 0; i < n; i++)
{   
    // You code here...

    if(i%50==0)
       Thead.sleep(200);
}
于 2012-12-05T11:01:17.433 に答える
0

次のような単純な条件をforループ内に記述できます。

for (int i = 0; i < n; i++)
{
 if(i % 100 == 0){// use 100 for 100 iterations and 50 for 50 iterations
   //your sleep code 
 }  
}
于 2012-12-05T11:01:43.113 に答える