1

在 for 循环中,我正在执行 Mongo DB 查询,该循环包含 1500 次迭代。那么无论如何,在50次迭代之后,我想给数据库一些时间,即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

像这样使用模数:

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

每次i 都是 50 的倍数,这将是真的

于 2012-12-05T11:00:55.910 回答
3

基于 Peter Lawrey 的回答,您可以将所有内容放在一个循环中,并在第一次迭代中避免模数和休眠:

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

这样,您可以将相对昂贵的模运算更改为便宜的按位运算&。在编程中使用二次方大小通常是一个好主意。

于 2012-12-05T11:20:00.623 回答
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 回答