描画速度

SwingとAWTで違うの?というはなし。JOGLとかはとりあえず考えない。
描画の実行は、repaint()を呼び出すか、getGraphics()でGraphicsをとってきて自分でsync()する(アクティブレンダリング)という選択肢がある。
repaint()は遅延する(遅延した分はまとめて一回にされる)?みたいなので、ゲームとかで明らかにカクカクしてるのにFPSを出すと予定通り、という事がおこる。Macではおこった。
一方アクティブレンダリングだとFPSは正確にだせるはず。

たぶん。

あとSwingはデフォルトでダブルバッファリングするので、自前でバッファ作んないでいいのかな?

参考

Java GUIプログラミングの、とてもBasicなFAQ(翻訳物)
http://homepage1.nifty.com/algafield/JavaGUIFaq19j.html
Javaでゲーム作りますが何か?
http://javagame.main.jp/index.php?%A5%A2%A5%AF%A5%C6%A5%A3%A5%D6%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0
WisdomSoft ダブルバッファリング
http://wisdom.sakura.ne.jp/system/java/swing/swing8.html

とりあえずいまテストした感じでは、AWTでもSwingでも速度は大差ないな…。AWTはFrameにCanvasをのせて、SwingはJFrameにJPanelで実装した。MacOSX10.4 でjava -versionは

java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-164)
Java HotSpot(TM) Client VM (build 1.5.0_07-87, mixed mode, sharing)

ちなみにMacだと、AWTで自力ダブルバッファ使わなくてもちゃんと出力される。Windowsだと普通にちらつくけど。
windowsでちょっと試したら、SWINGの方が少し速かった。
ゲーム作るならSwingで自力ダブルバッファなしアクティブレンダリングあり、がいいのかな。

上限60FPSで640x480にランダムな矩形を毎フレームたくさん描くプログラムで試してみた。
AWTはどちらも自力ダブルバッファ、Swingはrepaint()は自力ダブルバッファなしで直書き、アクティブレンダリングは自力ダブルバッファ。
マックでの結果は

GUI 矩形の数 repaint() アクティブレンダリング
AWT 500 60FPS 53FPS
AWT 2000 60FPS 16FPS
Swing 500 60FPS 55FPS
Swing 2000 60FPS 18FPS

こんな感じ。
repaint()の方が速いけど、画面はあきらかにカクカクしている。もちろんアクティブレンダリングもカクカクしてるが。
つまり内部での実行速度的には60FPSだけど、画面表示は60FPSもない。たぶん。
不思議だなぁ。
矩形作る処理が長引いてsleepが短いorない→repaint()呼び出し→描画する時間もないまま次の矩形作成処理→なんとか隙をぬってorムリヤリrepaint()を進めたけど60FPS出てない みたいな感じなのか?わからん…

windowsだとこんなかんじ

GUI 矩形の数 repaint() アクティブレンダリング
AWT 500 40FPS 39FPS
AWT 2000 46FPS 11FPS
Swing 500 40FPS 39FPS
Swing 2000 46FPS 10FPS

なぜ矩形の数を増やしたのに速くなりますか?repaint()は謎だらけだぜ…


マックでBufferStrategyも使ってみた。

GUI 矩形の数 repaint() アクティブレンダリング BufferStrategy
AWT 500 60FPS 53FPS 41FPS
AWT 2000 60FPS 16FPS 13FPS
Swing 500 60FPS 55FPS -
Swing 2000 60FPS 18FPS -

遅いじゃん…なんでよ。windowsだと?

GUI 矩形の数 repaint() アクティブレンダリング BufferStrategy
AWT 500 40FPS 39FPS 50FPS
AWT 2000 46FPS 11FPS 14FPS
Swing 500 40FPS 39FPS -
Swing 2000 46FPS 10FPS -

こっちは速くなった…ぬぅ。

テストに使ったソース
http://homepage.mac.com/kskeil/SwingSpeedTest.java
http://homepage.mac.com/kskeil/AwtSpeedTest.java
http://homepage.mac.com/kskeil/BSSpeedTest.java


上のwindowsってのは全部VMWwareFusionで動かしてたんだけど、BootCampでうごかしてみた。

GUI 矩形の数 repaint() アクティブレンダリング BufferStrategy
AWT 500 60FPS 28FPS 50FPS
AWT 2000 60FPS 7FPS 13FPS
Swing 500 60FPS 23FPS -
Swing 2000 57FPS 7FPS -

repaint()は高速化、アクティブレンダリングは低速化した。へぇ。よくわかんねぇ…

アクティブレンダリングで自力ダブルバッファなしにしてみる@Mac

GUI 矩形の数 repaint() アクティブレンダリング(自力DB) アクティブレンダリング(直書き) BufferStrategy
AWT 500 60FPS 53FPS - 41FPS
AWT 2000 60FPS 16FPS - 13FPS
Swing 500 60FPS 55FPS 50 -
Swing 2000 60FPS 18FPS 13 -

…もうぜんぜんわからん。なんで直書きの方が遅いんだ?

と言う事で、よくわからんなりにまとめ。

  • 正確な画面更新が必要な場合(ゲームとか)はアクティブレンダリングでがんばってください。
  • AWTとSwingはぶっちゃけどっちでもいいです。
  • ダブルバッファは自力でやるのがいいと思います。
  • 更新速度(FPS)があがらない時の対応は自分でやってください。
  • 検証終わり。

っていうかなんでアクティブなんだろ。パッシブの逆だからか?でも同期レンダリングとかの方がネーミングとしてはわかりやすいよーな…