2

私は 2008 年以降のマシンで開発を行っていますが、残念ながら現時点ではアップグレードできません。私が構築しているこのツールのパフォーマンスを最適化する必要があります。

私のプロジェクト全体はかなり大きく、現在、後でメイン プロジェクトのマップを作成するために使用する独自のマップ エディタを作成しています。これはかなり単純で、マップが所有する「タイル」の配列をロード、保存、および編集するように設計されています。基本的には、私のニーズに合わせてカスタマイズされた 2D マップ エディターです。

エディタのプレビュー


マップがエディターに読み込まれると、そのタイルセット (1 つの大きな BufferedImage) が個々のタイル (小さな BufferedImage を含む) に分割され、GUI の右側にアイコン付きの JLabels の大きな束に読み込まれます。さまざまな Swing LayoutManager を使用して、目的の配置を実現しました。

MapCanvas 領域内では、基本的に同じことが行われます。空かどうかに関係なく、各タイルにはアイコン付きの JLabel があり、グリッドにロードされます。Java2D を使用して設計および描画するよりも Swing コンポーネントを使用する方が効率的かどうかについて以前に尋ねたことがありますが、それはあまり問題ではないという意見で一致しました (正直に言うと、Swing はおそらく私が作成するものよりも優れているでしょう)。自分)。


私の問題は、各 JLabel とそのアイコンを相互接続する方法に起因していると思います。

私の目標は、作成しなければならない重複するアイコンの数を減らすことでした。これにより、理論的にはメモリ使用量と CPU 使用量が削減されるはずです。エディター内のタイルは次のように操作されます。

  • 「スタンプ」するタイルが選択されていない場合は、JLabel のアイコンの上に塗りつぶされた色のアルファ合成があり、それがホバーされていることを示し、MouseExit に戻ります。
  • アクティブなスタンプ ツールにタイルがある場合、そのタイルの画像が JLabel のアイコンを一時的に置き換えて、ホバーされていることを示し、MouseExit で元に戻ります。
  • アクティブなスタンプ ツールにタイルがあり、JLabel をクリックすると、元に戻さない限り、その JLabel のアイコンがアクティブなスタンプ タイルに「永続的に」設定されます。
  • グリッド線を表示するオプションがオンになっている場合、各 JLabel のアイコンは ImageFactory を介して処理され、上端と左端に沿って破線が実行されます (図に示すようにグリッドを形成します)。 JLabel の preferredSize は収容するように設定されており、ImageFactory でアイコンのサイズを変更する必要があります (グリッド線は状況に応じて適用されます)。


Map をエディタにロードすると、対応する BufferedImage (空かどうかに関係なく) を指定して、各 JLabel が作成され、Map のフィールド ArrayList にスローされます。レイアウトが正しく見えるように preferredSize が設定され、MapCanvas (単なる JPanel) に追加されます。

JLabel を Key として渡し、BufferedImage を取得できるように、さまざまな ArrayList オブジェクトと HashMap オブジェクトを作成しました。そうすれば、JLabel の上にカーソルを置くと、MouseEvent はイベントのソースをリスナーに送り返すことができ、受信した JLabel に基づいて正しい BufferedImage を取得できます。画像は、上記のいずれかの方法で ImageFactory クラスによって処理できます。

したがって、基本的に JLabel が MouseEvent を受け取ると、次のようになります。

  • MouseEvent がソース JLabel を ActionListener に送信する
  • リスナーは、ソース JLabel をキーとして使用して、目的の BufferedImage チャンクを取得します
  • BufferedImage チャンクは、それに応じて処理されます (これは、カラー アルファ コンポジット、それに適用されるズーム係数、追加されるグリッド線、またはこれらの組み合わせである可能性があります)。

これを行うより良い方法はありますか?これは私の 2 年前のラップトップでは目立った負担にはなりませんが、古いデスクトップ マシンでマウスが JLabel と対話するときに非常に顕著な遅延が発生します。

どちらも積極的に開発しているので、環境をスムーズに動かしたいし、それがメモリとCPUの使用率を厳しくしなければならないということなら、それでいいのです。

しかし、メモリ効率の良いシステムを思いつくことはできないようです。

ArrayLists と HashMaps が問題ですか? 多くの画像操作が問題ですか?

私はすでにさまざまな方法で JLabel の「setName(String)」メソッドを利用しています (たとえば、各 JLabel には、JLabels の 1 次元配列内の位置と、グラフ上の x 座標と y 座標を含む名前があります)。 、つまり "maptile#24:1,9") ですが、それには配列を反復処理する必要があり、キーを使用して BufferedImages を具体的に取得する方が効率的であることを願っていました。

4

1 に答える 1

0

Java コレクションは動的です。つまり、データを追加するとサイズが変更されます。サイジング関数 (ArrayList およびおそらく HashMap で使用される) の実際のモデルは、容量に達したときに容量を 2 倍にするのと似ています。これは、メモリ内で新しいブロックを宣言し、格納されているすべてのデータをコピーすることで構成されます。

HashMapおよびのそれぞれの最大可能サイズがわかっている場合はArrayList、初期容量を使用するコンストラクターを使用することでメリットが得られる場合があります。ヒア&ヒアこれにより、必要以上のメモリを使用するのを防ぐことができます。また、容量の増加による遅延の可能性を防ぎます。

また、各タイプのドキュメントの最初の数段落を読むと、効率的な使用法 (例: HashMaps loadfactor) の適切な説明が得られるため、役立つ場合があります。

他のタイプの List および Map を検討することも役立つ場合があります (実装の違いを認識していない場合)。たとえば、LinkedListは よりもはるかに効率的な削除および挿入操作を行いArrayListますが、目的のインデックスArrayListに到達するために前の各インデックスを走査する必要があるため、 は目的のインデックスにArrayList直接アクセスできます。

ただし、これらの推奨事項に基づいて行った変更がどれほど注目に値するかを推測するのは困難です。

于 2013-08-14T09:28:15.690 に答える