【发布时间】:2014-07-31 06:36:29
【问题描述】:
我有以下 10000000x2 矩阵:
0 0
1 1
2 2
.. ..
10000000 10000000
现在我想把这个矩阵保存到int[][]数组:
import com.google.common.base.Stopwatch;
static void memory(int size) throws Exception {
System.out.println("Memory");
Stopwatch s = Stopwatch.createStarted();
int[][] l = new int[size][2];
for (int i = 0; i < size; i++) {
l[i][0] = i;
l[i][1] = i;
}
System.out.println("Keeping " + size + " rows in-memory: " + s.stop());
}
public static void main(String[] args) throws Exception {
int size = 10000000;
memory(size);
memory(size);
memory(size);
memory(size);
memory(size);
}
输出:
Keeping 10000000 rows in-memory: 2,945 s
Keeping 10000000 rows in-memory: 408,1 ms
Keeping 10000000 rows in-memory: 761,5 ms
Keeping 10000000 rows in-memory: 543,7 ms
Keeping 10000000 rows in-memory: 408,2 ms
现在我想把这个矩阵保存到磁盘:
import com.google.common.base.Stopwatch;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
static void file(int size, int fileIndex) throws Exception {
Stopwatch s = Stopwatch.createStarted();
FileOutputStream outputStream = new FileOutputStream("D:\\file" + fileIndex);
BufferedOutputStream buf = new BufferedOutputStream(outputStream);
for (int i = 0; i < size; i++) {
buf.write(bytes(i));
buf.write(bytes(i));
}
buf.close();
outputStream.close();
System.out.println("Writing " + size + " rows: " + s.stop());
}
public static void main(String[] args) throws Exception {
int size = 10000000;
file(size, 1);
file(size, 2);
file(size, 3);
file(size, 4);
file(size, 5);
}
输出:
Writing 10000000 rows: 715,8 ms
Writing 10000000 rows: 636,6 ms
Writing 10000000 rows: 614,6 ms
Writing 10000000 rows: 598,0 ms
Writing 10000000 rows: 611,9 ms
不应该更快地保存到内存吗?
【问题讨论】:
-
您没有考虑到所有现代操作系统都有缓存,因此当您写入文件时,并不一定意味着会立即触及物理磁盘
-
OutputStream是缓冲的,因此它只会写入内存,直到缓冲区已满再将其写入磁盘...您可以尝试在每次迭代时刷新缓冲区或完全摆脱它。 .. -
您没有直接写入 文件。您正在写入内存中的流。然后它将被异步写入硬盘。
-
@MadProgrammer 默认缓冲区大小仅为 8K。当然,OP 写的远不止这些。
-
这里的 cmets 是正确的,
BufferedOutputStream中的缓冲和操作系统缓冲区缓存都会掩盖物理磁盘写入的延迟。我将在写入之后添加调用buf.flush()然后outputStream.getChannel().force(true)将强制写入一直到物理磁盘。大多数应用程序不会这样做,但如果您需要持久写入,它会很有用。