Swingの最適化と実装については、他の回答を参照してください。私の回答はJavaFX固有です。
JavaFXの実装に固執する場合は、次のことを試してください。
- node.setCache(true)を使用して、ノードのキャッシュをオンにします。
- node.setCacheHint(CacheHint.SPEED)を使用して、高速ノード変換を有効にします。
- 効果のない実装と効果のある実装を提供し、効果のない実装のパフォーマンスが著しく向上するかどうかを確認します。(その場合は、より効率的なエフェクトチェーンを使用するか、一部のエフェクトを完全に放棄する必要があります)。
- JavaFXシステム要件をチェックして、セットアップがハードウェア/OS/ドライバーの組み合わせに関するハードウェアアクセラレーションの最小要件を満たしていることを確認します。
- リージョンとcssベースの処理を使用している場合は、 cssシステムがあまり多くのオーバーヘッドを引き起こさないように注意してください(たとえば、cssを使用しないバージョンのコードを用意してそのパフォーマンスを比較するなど)。
- 必要に応じて、詳細レベルのズームを実装します(たとえば、ズームアウトすると、家のタイルごとに個別の画像ではなく、家全体の単一の画像が提供されます)。
- 特定の画像を1回だけロードし、それを複数のImageViewで再利用していることを確認してください。
- プロファイラーを使用してボトルネックを特定します。
- テストCPUまたはグラフィックカードを変更して、どちらかがボトルネックになっていないかどうかを確認します。
- JavaFXの多くの内部パフォーマンス最適化を特徴とするJava8プレビューを試してください。
- 多数の画像を読み込む場合は、バックグラウンド読み込みを使用し、画像の読み込み中にアニメーションまたはプログレスバーを前面で再生します。
- 大量の画像をロードする場合は、Imageコンストラクターで事前にスケーリングして、メモリを大量に消費したり、追加のピクセルに(潜在的に)追加の処理能力を必要としないようにします(大量の画像を使用している場合にのみ考慮します)。さまざまな非常に高解像度のテクスチャ-これは実行していないようです)。
例えば:
Image tile = new Image("tile.png");
Group house = new Group();
house.setCache(true);
house.setCacheHint(CacheHint.SPEED);
Effect lighting = new Lighting();
for (int i = 0; i < houseWidth; i++) {
// here is the critical part => don't do new ImageView(new Image("tile.png"))
ImageView tileView = new ImageView(tile));
tileView.setEffect(lighting);
tileView.setCache(true);
tileView.setCacheHint(CacheHint.SPEED);
house.add(tileView);
}
マントリッドの提案は興味深いものです。JavaFXを使用すると、ダーティレクタンギュラーアルゴリズムを自分で実装する必要はないと思います(基盤となるプラットフォームがダーティリージョンの処理を処理できるため)。これは一般的なメカニズムであるため、特定のケースに必要なレベルの最適化を提供していない可能性があります。その場合、ダーティ処理を自分で処理する必要があります(たとえば、シーングラフからノードを削除して再追加することによって)必要に応じて)。
さらに、画像のぼかし/明るさなどを事前に計算するには、JavaFXで効果を定義し、効果をオフスクリーンのImageViewノードに適用してから、オフスクリーンのImageViewノードのスナップショットを取得して事前に計算された画像を取得します。この手法により、ConvolveOpメカニズムを使用して再実装することなく、既存のJavaFXエフェクトパイプラインを再利用できます。おそらく、ImageViewノードでcacheをtrueに設定し、cacheHintを速度に設定するだけで、同じパフォーマンスレベルが得られる可能性があります。これは、舞台裏で同様のことを行うと思います(つまり、メモリ使用量が増える代わりに速度が上がる)。
JavaFXシーングラフは非常に効率的で、何千ものノードを処理できます。ただし、アプリケーションにはそれ以上のものがある場合があります。上記の最適化ポイントが役に立たない場合は、ノード数を計算し、JavaFXアプリケーションの詳細を知っているJavaFX開発者がいるopen-jfxメーリングリストに質問(およびおそらくいくつかのソース)への参照を投稿することをお勧めします最適化はです。
JavaFX 8は、JavaFX 2.2の(ほとんど役に立たない)3Dシーングラフよりもはるかに優れた3Dシーングラフのサポートを備えています。現在のアプリケーションは、2Dオブジェクトを変換し、照明効果を個別に適用し、各タイルの明るさを調整して3Dの外観を得るpsuedo-3dのようです。その場合、統合された3D照明モデルで完全にハードウェアで高速化された3Dシーングラフを使用すると、パフォーマンスが向上し、見栄えが良くなり、操作が簡単になる可能性があります。アプリケーションのコンテキストで評価して、それがアプリを2DJavaFXシーングラフから3DJavaFXシーングラフに、またはJavaFXからSwingまたはlibgdxなどの他の技術に切り替える価値があります。
補遺
Mizurの追加の質問のいくつかに対する回答:
では、なぜそれらはそれほど電力を消費するのでしょうか?
私の答えからわかるように、パフォーマンスには多くの側面があります。そのため、何かが電力を消費する理由について1つの特定の理由を特定することは、困難な場合があり、不可能な場合があります。パフォーマンスの問題の原因となるものの組み合わせである場合もあります。最大の勝利は通常、最も内側のループで実行されるものを最適化すること、または問題を解決するために使用される戦略を変更することによってもたらされます。
そんなに必要な場合は、タイルを動かしてください、それとも表示するだけですよね?
移動するものにのみリソースを消費するという点で、JavaFXシーングラフにはそのためのいくつかの最適化があり、キャッシュヒントのようなものはそのパフォーマンスをさらに向上させることができます。おそらく、特定のユースケースやシステムの使用方法には不十分です。システムの負荷を軽減するために、アルゴリズムを変更する必要がある場合があります。
このImageviewの手法を使用して各建物の画像を生成し、これらの建物の画像を最終シーンに統合する方法はありますか?
はい-多くの画像とノードを使用して建物をオフスクリーンシーンにレンダリングし、オフスクリーンシーンのスナップショットを作成して単一の画像を作成し、その画像を最終シーンにオーバーレイすることができます。