在 for 循环中,我正在执行 Mongo DB 查询,该循环包含 1500 次迭代。那么无论如何,在50次迭代之后,我想给数据库一些时间,即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
像这样使用模数:
for (int i = 0; i < n; i++){
if( i%50 == 0){
Thead.sleep(200);
}
}
每次i
都是 50 的倍数,这将是真的
基于 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
这样,您可以将相对昂贵的模运算更改为便宜的按位运算&
。在编程中使用二次方大小通常是一个好主意。
我认为这通常不是一个好主意,但是当你问:
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
}
}