1

目前我有一个解析器设置,它将解析约 200 万条记录的 csv 文件。然后我应用一些过滤算法来清除我想要包含/排除的记录。最后将所有内容写回一个新的 csv 文件。

我做了一些基准测试,结果发现将数据写入 csv 非常昂贵,并且在同时过滤和附加到文件时会导致速度大幅下降。我想知道我是否可以执行所有过滤,将要写入的行放入队列中,然后当队列已满或所有过滤完成时,让第二个进程自行执行所有写入。

所以基本上总结一下:

Read line 
Decide whether to discard or keep
if I'm keeping the file, add it to the "Write Queue"
Check if the write queue is full, if so, start the new process that will begin writing
Continue filtering until completed

感谢你的帮助!

编辑: 我写的方式如下:

FileWriter fw = new FileWriter("myFile.csv");
BufferedWriter bw = new BufferedWriter(fw);
while(read file...) {
   //perform filters etc...
    try {
        bw.write(data.trim());
        bw.newLine();

    }catch(IOException e) {
        System.out.println(e.getMessage());
    }
4

2 回答 2

3

读取和写入进程都受 I/O 限制(寻找磁盘上的扇区并在内存中执行磁盘 I/O),而过滤过程则完全受 CPU 限制。这是多线程的一个很好的候选。

我会使用三个线程:读取、过滤和写入。这需要两个队列,但没有理由在处理之前等待队列变满。

  • 读取器线程从文件中读取数据并将行追加到传入队列中。
  • 过滤器线程从传入队列中获取行并将通过过滤器的行写入传出队列。
  • 写入器线程从传出队列中获取行并将它们写入新文件。

确保使用缓冲的读取器和写入器来最小化读取器和写入器线程之间的争用。您希望尽量减少磁盘查找,因为这将成为瓶颈,假设过滤过程相当简单。

于 2012-07-17T03:51:15.533 回答
0

除非您对使用 Spring 有任何限制,否则您可能需要考虑使用 Spring Batch。

于 2012-07-17T04:23:17.917 回答