torutkのブログ

ソフトウェア・エンジニアのブログ

アニメーションを使用するJavaFXプログラムのCPU使用率低減(フレームレート)

id:torutk:20160608 で、JavaFXのアニメーションを使ったプログラムのCPU使用率を低減させるために、描画するノードをキャッシュする方法を確認しました。

キャッシュ化によって、確かにある程度はCPU使用率が低減しましたが、まだ他のプログラムを邪魔をしないという目標には届かないし、ノートPCで動かすとファンが唸り出しています。

これは、JavaFXのアニメーションが60fps(16ms周期)で処理を更新しているためです。このFPSを下げることができれば処理を減らしCPU使用率が下がるはずです。
で、調べていたら、実は簡単にアニメーション処理の更新間隔FPSを変えられることが分かりました。

Timelineクラスのコンストラクタに、targetFramerateを指定するシグニチャがあります。

public Timeline(double targetFramerate)

意味の説明は、AnimationクラスのgetTargetFramerateメソッドのJavadocに記載されています。

ターゲット・フレームレートは、このAnimationが実行される最大フレームレート(フレーム/秒)です。特に複雑なAnimationsによってシステム・リソースが過剰消費されないようにする場合などに使用します。デフォルトでは、Animationのフレームレートは明示的には制限されていません。つまり、Animationは、基礎となるプラットフォームに最も適したフレームレートで実行されます。

ここで、例えばnew Timeline(10.0); と記述すれば、アニメーションの更新が最大で10fpsに抑えられるということですね。
targetFramerateを指定しなかった場合が、60fps(プラットフォームに適したレート)となるわけですね。

ということで、アナログ時計プログラムでTimelineをnewしている個所を変更します。

public class AnalogClockController implements Initializable {
    private final static double FRMAE_RATE = 10d;
    :
    private Timeline createRotateTimeline(Duration duration, int startAngle, Rotate rotate) {
        Timeline timeline = new Timeline(FRAME_RATE);
        :
    }
    :
}

昨日同様、WindowsのtypeperfコマンドでjavaプロセスのCPU使用率を毎秒1分間取得します。測定環境は昨日と同じです。


Cache指定なし Cache指定あり Cache・10fps指定 Cache・5fps指定
23.2% 13.4% 7.8% 4.1%

とさらに半分近く低減することができました。ついでに、5fpsでも測定したので記載しています。