我正在将大量字符串写入文件,并注意到在某些时候,写入操作开始比以前花费更多时间。大多数字符串都是唯一的,并且是在运行时使用StringBuilder
生成的,所以我认为这是问题所在,但结果还有其他原因。
我写了一个快速程序,看看发生了什么
public static void main(String[] args) {
long time, t1, t2;
int n = 10000;
int threshold = 10;
try {
BufferedWriter out = new BufferedWriter(new FileWriter("C:\\temp\\out.txt"));
for (int i = 0; i < n;i++) {
t1 = System.currentTimeMillis();
out.write("test\r\n"));
t2 = System.currentTimeMillis();
time = t2 - t1;
if (time > threshold) {
System.out.println(time);
}
}
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
我设置了一个阈值来过滤掉占用时间最短的写入操作。我把它设置为10毫秒。
当n = 10 000
时,没有任何内容打印出来,这意味着写入很快。当我将n
增加到100 000
,1 000 000
,10 000 000
时,会打印出几个数字。然后在100 000 000
我开始看到很多数字被打印出来。将它增加到1 000 000 000
,许多写入操作需要几十到几百毫秒,这大大降低了吞吐量。
出现这种情况的原因可能有很多,例如我使用旋转磁盘驱动器或磁盘碎片。我已经尝试将缓冲区大小增加到1 MB或10 MB但它似乎没有帮助(事实上它似乎使事情变得更糟)。
我能做些什么来避免吞吐量超时的突然下降?
答案 0 :(得分:3)
大多数操作系统,例如Windows和Linux允许您对磁盘进行无意义的写入。例如。你可以在实际磁盘上写入最多10%的主内存。这种方法非常快,但是一旦达到此阈值,您只能以磁盘可以写入的速度写入。
我能做些什么来避免吞吐量超时的突然下降?
答案 1 :(得分:1)
使用BufferedWriter
编写小文件时,在编写器关闭之前,缓冲区不会刷新到磁盘,而基准测试根本不会对其进行测量。大多数写操作都将在内存缓冲区上运行,这将非常快。为了更好地了解性能,您需要在第一次写入之前启动计时器,并在调用close()
完成后停止计时器,并将其除以写入数据的总大小以获得度量平均吞吐量。