4

我有一个带有 switch 语句的 while 循环:

while(true) {
        switch(state) {
        case LOADING :
            //THIS IS THE IMPORTANT PART
            //view loading screen (already set by default)
            contentPane.repaint();
            if(tick == 400000) {
                //state = GameState.MENU;
                System.out.println("Reached " + gameTick);
            }
            break;
        case MENU :
            //view menu
            break;
        //some other cases without content, left them out here
        }
        tick++;
        if(tick < 400000) {
                System.out.println(tick);
        }
        if(tick == Long.MAX_VALUE) {
            tick = 0;
        }
    }

现在这段代码执行得很好,它显示了加载屏幕(只要它被重复调用,它上面就有移动的点,所以我知道它什么时候停止),输出从 1 计数到 400000 和那个数字印刷

399998
399999
Reached 400000    

(最后3行输出)

应用程序进入全屏状态,当我 alt+tab 退出时,计数器通常在 130K 左右,我看着它移动到 400K。

但是,如果我删除打印此数字的 if 语句:

if(tick < 400000) {
    System.out.println(tick);
}

加载屏幕永远不会移动,当我 alt + tab out 时,已经达到 400K。

同样奇怪的是,加载屏幕有三个“外观变化”,一个在 100 次调用它的 paintComponent 方法时,一个在 200 次调用时,一个在 300 次调用时,这会将计数器重置为 0。所以基本上,它应该有每 100 个滴答声外观变化。在第一种情况下,使用执行时间较长的 if 语句,我看到了变化,但远没有我预期的那么频繁。在第二种情况下,我根本看不到它们(我可以想象它们发生得太快了)。

所以我的问题是,是什么造成了执行时间的如此大的差异,以及导致paintComponent 方法似乎被调用的次数和循环迭代400.000 次的差异的原因是什么?

所有想法都表示赞赏。

4

5 回答 5

5

写入控制台,尤其是 MS-DOS 控制台,非常慢。您应该尽量减少写入控制台的行数。如果您必须写入大量数据,我建议您将其写入文件,因为它可以显着加快。

我假设这是在另一个线程中完成的,并且您没有占用 GUI 线程。

于 2012-10-03T14:40:37.610 回答
2

repaint()方法不会立即重绘组件,只是向 AWT/Swing 系统发出信号以重绘组件。因此,如果您repaint()快速调用 10 次,则很有可能只会重新绘制一次。

现在,如果您查看循环,它不会执行任何需要很长时间的操作(请注意,repaint()不会重新绘制)。如果您System.out.println()在循环中添加调用,它将显着增加循环内要完成的工作。

于 2012-10-03T14:42:09.493 回答
1

写入控制台是一项相对耗时的任务,尤其是与什么都不做相比。这大大减慢了执行速度。如果您将输出重定向到文件,您的循环将比不打印慢,但比打印到控制台快。

这就是打印和不打印执行速度差异很大的原因。

于 2012-10-03T14:42:38.313 回答
1

尝试类似的东西,

tick++;
Thread.sleep(100);

并检查您假设的变化是否正在发生。

于 2012-10-03T14:43:15.270 回答
1

任何一种接口都比没有接口慢很多倍。无论是控制台还是图形界面。这主要是因为访问图形设备所需的所有额外代码。更不用说硬件延迟了。

于 2012-10-03T14:52:47.700 回答