我有一个50,000,000行csv
文件。
name, salary, text
anna, 100, good
mary, 50, low
amber, 60, ok
...........
我需要添加主索引p_index
p_index, name, salary, text
1, anna, 100, good
2, mary, 50, low
3, amber, 60, ok
...........
到目前为止,我逐行使用BufferedReader
读取。然后使用PrintWriter
从原始csv复制到新的csv。然而,这种方法很慢。 。大约20分钟。有没有办法更快地添加自动增量值。这是我的代码
public class Test {
static PrintWriter pw;
public static void main(String[] args) {
FileReader fr = new FileReader("test.csv");
File file = new File("test2.csv");
BufferedReader reader = new BufferedReader(fr);
String line = reader.readLine();
pw = new PrintWriter(file);
pw.println("P_INDEX," + line);
int i = 0;
while ((line = reader.readLine()) != null) {
pw.println(i + "," + line);
i++;
}
pw.close();
System.exit(0);
}
}
任何人都可以对我的代码进行更正以提高其工作速度吗?
由于
答案 0 :(得分:2)
一些可能性。
对任何更改进行基准测试,针对最佳缓冲区大小进行有条理的“二进制搜索”等。使用较小的文件,在几十秒内处理。
不要使用String
,只使用原始字节数组。文件的8位字符编码和Java字符串的16位unicode之间的转换是像这样的批量数据情况下的性能杀手(但是在文件的开头注意UTF-8 BOM,如果有一个插入后的第一个字节它)。
如果您有定期格式化的固定列CSV文件,则最小行长度。扫描下一行的缓冲区时,可以跳过这么多字节。
使用java.nio
优化缓冲区大小(参见上面的第1项)。
使用2个线程处理前一个时读取下一个缓冲区。也许把写入第三个线程(在这种情况下,扫描可能与性能无关,没有点跳过部分行)。
答案 1 :(得分:0)
默认情况下,PrintWriter具有相当小的缓冲区。您可能会提高性能,确保使用带有更大缓冲区的BufferedWriter创建PrintWriter。例如:
new PrintWriter(new BufferedWriter(new FileWriter(file), 1000000));
如果您已经了解了数据集的大小,您还可以为读取器和写入器设置缓冲区大小,以减少对磁盘的读/写次数。
使用~4Gb的示例文件,您的示例代码编写耗时约53秒。使用带有BufferedWriter的相同输入文件并使用10Mb缓冲区写入需要大约48秒