for ループ内で Mongo DB クエリを実行しています。ループには 1500 回の反復が含まれています。とにかく、50回の反復の後、DBに時間を与えたいということはありますかThread.currentThread().sleep(200);
では、50 回ごとにしばらく停止する方法を教えてください。
for (int i = 0; i < n; i++){
// ????
}
これにはモジュロを使用します
if( i % 50 == 0 ){
Thread.sleep(200);
}
一部の 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
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 の累乗のサイズを使用することは、一般的には良い考えです。
次のようにモジュロを使用します。
for (int i = 0; i < n; i++){
if( i%50 == 0){
Thead.sleep(200);
}
}
i
これは、50 の倍数になるたびに真になります。
これは一般的に良い考えではないと思いますが、あなたが尋ねたとき:
if (i % 50 == 0 && i!=0) {
// Do something
}
すべての「n」クエリをスリープ状態にする方法に関係なく、これが本当にあなたがやりたいことなのかどうか疑問に思います。IDのリストを取得して各ドキュメントのデータベースにクエリを実行する代わりに、より適切なクエリをデータベースに送信し、おそらく最適化されたクエリAPIを使用して情報を検索/返すことはできません。
for (int i = 0; i < n; i++)
{
// You code here...
if(i%50==0)
Thead.sleep(200);
}
次のような単純な条件を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
}
}