Javaシリアライゼーションについて質問があります。
FileOutputStream と BufferedOutputStream を Dataoutputstream と組み合わせて使用して、サイズ int[] array = new int[2^28] の 10 個の配列をハード ディスクに書き出すだけです (これはちょっと大きいことはわかっていますが、そのようにする必要があります)。 . 各シリアル化の前に、新しい FileOutputstream と他のすべてのストリームを作成し、その後、ストリームを閉じてフラッシュします。
問題: 最初のシリアル化には約 2 秒かかり、その後 tp 17 秒増加し、このレベルにとどまります。ここで何が問題なのですか?コードを調べてみると、FileOutputStreams が writeByte(...) に膨大な時間を費やしていることがわかります。これは HDD キャッシング (フル) によるものですか? どうすればこれを回避できますか? クリアできますか?
これが私の簡単なコードです:
public static void main(String[] args) throws IOException {
System.out.println("### Starting test");
for (int k = 0; k < 10; k++) {
System.out.println("### Run nr ... " + k);
// Creating the test array....
int[] testArray = new int[(int) Math.pow(2, 28)];
for (int i = 0; i < testArray.length; i++) {
if (i % 2 == 0) {
testArray[i] = i;
}
}
BufferedDataOutputStream dataOut = new BufferedDataOutputStream(
new FileOutputStream("e:\\test" + k + "_" + 28 + ".dat"));
// Serializing...
long start = System.nanoTime();
dataOut.write(testArray);
System.out.println((System.nanoTime() - start) / 1000000000.0
+ " s");
dataOut.flush();
dataOut.close();
}
}
どこで dataOut.write(int[], 0, end)
public void write(int[] i, int start, int len) throws IOException {
for (int ii = start; ii < start + len; ii += 1) {
if (count + 4 > buf.length) {
checkBuf(4);
}
buf[count++] = (byte) (i[ii] >>> 24);
buf[count++] = (byte) (i[ii] >>> 16);
buf[count++] = (byte) (i[ii] >>> 8);
buf[count++] = (byte) (i[ii]);
}
}
そして `protected void checkBuf(int need) throws IOException {
if (count + need > buf.length) {
out.write(buf, 0, count);
count = 0;
}
}`
BufferedDataOutputStream は BufferedOutputStream を拡張し、fits フレームワークに付属しています。単純に BufferedOutputStream と DataOutputStream を組み合わせて、大きな配列を書き込むときのメソッド呼び出しの数を減らします (これにより、はるかに高速になります... 最大 10 倍...)。
出力は次のとおりです。
ベンチマークの開始
スタートラン 0
2.001972271
スタートラン1
1.986544604
スタートラン2
15.663881232
スタートラン3
17.652161328
スタートラン 4
18.020969301
スタートラン 5
11.647542466
スタートラン 6
なぜこんなに時間が増えているのでしょうか?
ありがとうございました、
イース