4

私はJavaプログラミングに非常に慣れていないので、初心者の質問を許してください:)。

開発を支援するために変更しているアプリケーションのファイル キャッシュとして LinkedHashMap を使用しています。これは、I/O オーバーヘッドを減らしてパフォーマンスを向上させるために行っています。これに関する問題は、他の多くの方法でオーバーヘッドが発生することです。

関連ソースはこんな感じ。


// Retrieve Data From LinkedHashMap  
byte grid[][][] = null;  
if(file.exists())
{  
    if (!cache.containsKey(file))  
    {
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis, 16384);
        ObjectInputStream ois = new ObjectInputStream(bis);
        cache.put(file, ois.readObject());
        ois.close();
    }
    grid = (byte[][][]) cache.get(file);
} else {
    grid = new byte[8][8][];
}

以下は、私がデータを保存するために使用するものです。データをロードする方法は正反対です。


ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(baos){{    def.setLevel(2);}};
BufferedOutputStream bos = new BufferedOutputStream(gos, 16384);
DataOutputStream dos = new DataOutputStream(bos);
// Some code writes to dos
dos.close();
byte[cx][cz] = baos.toByteArray();
baos.close();
cache.put(file, grid);

そして、これがキャッシュの宣言です。


private static LinkedHashMap<File, Object> cache = new LinkedHashMap<File, Object>(64, 1.1f, true)
{protected boolean removeEldestEntry(Map.Entry<File, Object> eldest) 
    {
        return size() > 64;
    }
}

私は Java ストリームのエチケットにあまり慣れていないので、上記のコードがお粗末に見える可能性が非常に高いです。また、バッファをどこに置くかなど、上記を行うためのより効率的な方法があると確信しています。

とにかく、私の主な問題は次のとおりです。単一のチャンクに対して何かを行う必要があるときはいつでも、すべてのグリッド データをオブジェクトに変換し、それをキャッシュに送信し、ファイルに書き込む必要があります。これは非常に非効率的な方法です。get(); する必要がないように、これを行うためのより良い方法があるかどうかを知りたいです。その 1 つのチャンクにのみアクセスする必要がある場合は、byte[8][8][] 配列全体。chunk = cache.get[cx]cz のようなことをしたいのですが、それほど単純ではないと確信しています。

とにかく、先に言ったように、もし答えが明白なら、質問を許してください。ご意見をお待ちしております:)。

ありがとう。

4

2 に答える 2

1

I/O オーバーヘッドを削減することが目的の場合は、byte[][][]オブジェクトをラッパー オブジェクトに配置して、ダーティ フラグの概念を追加するのはどうでしょうか。

こうすることで、変更時にファイルが書き込まれる回数を減らすことができ、キャッシュを使い終わったとき、または完全なキャッシュに挿入するときに最も古いオブジェクトを削除しようとしているときにのみ、ダーティ オブジェクトをディスクに書き込むことができます。

于 2010-12-21T21:17:51.153 に答える
0

データを保持するために、新しいクラスを作成することから始めByteMatrix3Dます。また、 を使用する代わりbyte[][][]に、計算されたオフセットを持つ 1 次元配列を使用します (たとえば、8x8x8 配列では、 のオフセットは[1][2][3]として計算できます1 * 64 + 2 * 8 + 3。この変更により、オブジェクト管理のオーバーヘッドが大幅に削減され、上位レベルのコードに影響を与えることなく、追加の変更を行います。

そして、私が行う最初の変更はMappedByteBuffer、ファイルへのアクセスに a を使用することです。これにより、オペレーティング システムが実際のデータを管理し、読み書きをプログラムに対して透過的にすることができます。

于 2010-12-21T21:18:23.593 に答える