【问题标题】:Why this while loop cannot print 1,000 times per seconds?为什么这个while循环不能每秒打印1000次?
【发布时间】:2015-06-21 16:23:12
【问题描述】:

以下 Java 方法旨在以 nLoopsPerSecond 次在 seconds 秒内每秒打印数字 i

public void test(int nLoopsPerSecond, int seconds) {
    double secondsPerLoop = 1.0/(double)nLoopsPerSecond;
    long startTime = System.currentTimeMillis();
    long currentTime;
    int i = 0;
    while ((currentTime = System.currentTimeMillis()) < startTime + seconds*1000) {
        System.out.println(i++);
        while (System.currentTimeMillis() < currentTime + secondsPerLoop*1000);
    }
}

通过以下调用:

test(1000,1);

我希望这种方法可以执行System.out.println(i++); 1,000 次,但我只得到了 63 次。

当我尝试使用此代码查看每个循环实际使用多少秒时

public void test(int nLoopsPerSecond, int seconds) {
    double secondsPerLoop = 1.0/(double)nLoopsPerSecond;
    long startTime = System.currentTimeMillis();
    long currentTime;
    int i = 0;
    while ((currentTime = System.currentTimeMillis()) < startTime + seconds*1000) {
        while (System.currentTimeMillis() < currentTime + secondsPerLoop*1000);
        System.out.println(System.currentTimeMillis() - currentTime);
    }
}

我希望它在每个循环中打印1 毫秒,但它会打印1516 毫秒。

请提出我的代码有什么问题。

【问题讨论】:

  • 我建议您输入您尝试执行的确切代码。这不会编译。例如 - seccond 是什么?另外-为什么在while循环中有while循环?
  • System.out.println 可能无法每秒向控制台输出 1000 次。少得多。
  • 作为在循环中使用printlln() 的替代方法,您可以使用您希望打印的值填充数据结构,然后在循环后立即显示它们。尝试一个 ArrayList 构造为已经大小为 1000 或尝试一个旧学校 int 数组大小为 1000。
  • @jite 我不这么认为,因为当我删除内部while 时,它最多打印 90,000++
  • 出于您的目的,看起来System.nanoTime() 会更有用,因为您没有从纪元开始测量时间。 stackoverflow.com/a/351571/1493294

标签: java loops time while-loop


【解决方案1】:

也许您在 Windows 上运行? System.currentTimeMillis() 参考底层操作系统时钟,在许多版本的 Windows 上只有 60Hz。

【讨论】:

  • From the API docs: "注意虽然返回值的时间单位是毫秒,但是值的粒度取决于底层操作系统,可能会更大。例如很多操作系统以几十毫秒为单位测量时间。”
  • 我从 System.currentTimeMillis() 更改为 System.nanoTime() 并解决了。出于这个原因,我认为你是对的。是的,我在 Windows 上运行(我尝试了 Windows Xp 和 Windows 8.1)
【解决方案2】:

尝试System.nanoTime(),因为您没有从纪元开始测量时间。 System.currentTimeMillis vs System.nanoTime

【讨论】:

    【解决方案3】:

    这可能是因为处理需要一些时间。处理器不仅仅将时间用于执行您的程序,它还在后台执行其他几个功能。因此,您可能会根据处理器负载得到不同的结果。

    【讨论】:

      【解决方案4】:

      您的输出控制台速度不够快。您没有提及如何运行测试以及输出的去向。使用的终端和缓冲区(未使用)的速度将限制程序输出数据的速度。如果运行无缓冲,您的程序将始终需要等待,直到新行打印在屏幕上。如果控制台等待屏幕重绘并且屏幕以 60Hz 的频率重绘,那么您将获得 16 毫秒/行和每秒大约 60 行。

      在 IntelliJ Idea 中运行没有内部循环的代码,我每秒得到大约 140.000 行(Idea 警告我,它没有显示每一行,因为我的输出太快了)。

      使用内部循环,我得到大约 800-900 行。发生这种情况是因为该进程可能被调度到 cpu 之外,或者由于其他原因(例如交换)而被阻止。 (如果我简化很多,通常桌面操作系统会以 1 毫秒的粒度进行调度。)

      【讨论】:

      • 我在带有 CPU Intell i5 的 Windows XP 上运行,但是当我删除内部 while 循环时,它会打印 90,000++,所以我相信这不是因为从打印到控制台的延迟,无论如何谢谢:D
      猜你喜欢
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 1970-01-01
      相关资源
      最近更新 更多