2012-10-03 58 views
3

我有一个switch语句一个while循环:添加System.out.println()会减慢执行速度(很多)?

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出来,已经达到了400K。

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

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

所有的想法appreceated。

+0

[This](http://stackoverflow.com/questions/4120528/repaint-in-a-loop)应该有所帮助。 – st0le

回答

4

写入控制台,特别是MS-DOS控制台,速度非常慢。你应该尽量保持你写入控制台的行数最少。如果你不得不写很多数据,我建议你把它写到一个文件中,因为它可以快得多。

我认为这是在另一个线程中完成的,而不是绑定GUI线程。

+0

令人难以置信的(至少对我来说)如何写入控制台显然比写入文件慢得多..无论如何感谢您的洞察力。但是,while循环的迭代次数和contentPane中的paintComponent被调用的次数也有所不同。我只是添加了一行打印paintComponent被执行的频率的计数器,并且每次都会变化。在400K while()迭代中,该方法似乎被称为255(最低结果)至677(最高结果)倍。它涉及到屏幕上的变化量,这是6次。你能解释一下吗? –

+0

GUI尽力忽略虚假的绘画调用。只要它比实际需要的数量多,而且不会太多就没有问题。 –

+0

如果您考虑在屏幕上打印一个字符所需的工作量,例如处理字体,其写入文件的速度要慢于写入不需要对每个字符做任何事情的文件,这并不奇怪。令人惊讶的是,MS-DOS窗口比同一台机器上的Swing GUI或xterm(运行Linux)慢得多。 –

2

repaint()方法不会立即重新绘制组件,只是指示AWT/Swing系统重新绘制组件。因此,如果您快速拨打repaint() 10次,那么很可能只会重新绘制一次。

现在,如果你看看你的循环,它不需要很长时间(注意repaint()不重绘)。如果您在循环中添加System.out.println()调用,它将显着增加循环中要完成的工作。

+0

感谢您的解释:) –

1

写入控制台是一项相对耗时的工作,尤其是与无所事事相比。这大大减缓了执行速度。如果将输出重定向到文件,则循环会比没有打印时慢,但比打印到控制台上要快。

这是造成执行速度差异很大的原因,无论是否打印。

+0

现在我知道为什么要将调试结果写入文件!感谢您的贡献:)。 –

1

尝试类似,

tick++; 
Thread.sleep(100); 

,并检查您应该变化是否正在发生。

+0

刚刚添加它,结果全部正常。把印刷品拿出来稍微短一些。现在让它进入睡眠状态(1),这已经显着减慢了它的速度,看看两个计数器是否因此而变得更接近彼此。会回来这个。 –

+0

在while循环的400K迭代中,paintComponent现在使用sleep(1)调用45662次。此行为由上面的其他答复者解释。感谢您的贡献! –

+0

欢迎,你有没有解决你的问题呢? –

1

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