2017-11-16 12 views
0

現在、タイルに基づいて2次元ゲームを開発中です。現時点では、私は全世界を救うためのプロセスを書いています。一般に、世界は10000×10 = 1.100.000ブロック大きいです。明らかに、それはJavaの問題ではありませんが、それはあります。Javaの2dタイル保存:繰り返し回数が1回につき5秒になるとループが遅くなる

は、ここに私のループです:

Material[][] blocks = g.gameState.getLevel().tiles; 
int y = 0; 
int blocksHor = g.gameState.getLevel().getBlocksHor(); 

for(int x = 0; x < blocksHor; x++) { 

    world += blocks[y][x] + " "; 

    if(x >= blocksHor - 1) { 
     x = 0; 
     y++; 
     System.out.println("LAYER " + y + " => " + (System.currentTimeMillis() - now) + " ms"); 
     now = System.currentTimeMillis(); 
    } 
} 

ループが理解することが少し難しいですが、私はすでにどこに私ができる最適化しようとしました。コンソールの出力は次のとおりです。

LAYER 1 => 86 ms 
LAYER 2 => 276 ms 
LAYER 3 => 424 ms 
LAYER 4 => 618 ms 
LAYER 5 => 561 ms 
LAYER 6 => 541 ms 
LAYER 7 => 755 ms 
LAYER 8 => 885 ms 
LAYER 9 => 1036 ms 

これらの処理は、最長で50秒以上かかることがあります。

このループで何が問題になっていますか?私は正直なところ、この問題をどのように解決すべきか分かりません。

ありがとうございました:)

+0

[StringBuilder](https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html)を試してみてください。 –

答えて

2

-phil確かにあなたが提示したコードは、あなたの問題の代表であるならば、問題はそれでいくつかのパフォーマンスの問題があります

world += blocks[y][x] + " "; 

で非常に可能性があります。まず、worldのタイプはStringで、Stringは不変です。したがって、演算子+を使用して連結するたびに、結果を保持するために新しい演算子を作成する必要があります。その文を実行するたびに少なくとも2回は実行し、最終的に収集する必要がある2Mガベージオブジェクトを全体的に生成します。

また、worldサイズが着実に増加するので、すべてのそれらの一時によって消費される組み合わされたメモリの中間値は、ブロックの総数の平方に比例します。たとえ各ブロックの文字列値が1文字だけであったとしても、これは大量のメモリになります。あなたは重大なガベージコレクションの問題に終わるつもりです。そして、あなたが進むにつれて、実際には着実に悪化するでしょう。大幅にはるかに少ないゴミを作成することにより、GCの問題を軽減する必要があり

StringBuilder worldBuilder = new StringBuilder(); 

// ... 

worldBuilder.append(blocks[y][x]).append(' '); 

ていますされます:これを改善するのに最初の試みとして、あなたはStringの代わりにStringBuilderにデータを蓄積し検討することもでき

それでも状態全体を保持するためにかなり大きなオブジェクトが必要になります。したがって、私はまた、何かを出力する前に、全体の表現をメモリに構築するのではなく、小さな塊にデータを蓄積し、それを出力することをお勧めします。

Material.toString()の実装を見てみると、文字列連結を実行することによって多くのゴミが生成される場合は、問題が拡大する可能性もあります。

+0

ありがとう!これは素晴らしい解決策であり、うまくいきます<3 – phil

+1

Lol、プロセスは1 msで実行されます。 Lmao – phil

関連する問題