6

我正在使用BufferReader.readlLine().

两个文件大小相同,为 130MB,但处理一个需要 40 秒,而另一个需要 75 秒。

我注意到一个文件有 180 万行,而另一个文件有 210 万行。但是,当我尝试处理具有相同大小的 300 万行的文件时,需要 30 分钟来处理。

所以我的问题是:

  1. 这种行为是因为缓冲区读取器的查找时间(我想知道如何BufferedReader工作或逐行解析文件?)

  2. 有什么方法可以更快地逐行读取文件吗?

好的朋友,我提供更多细节。

我使用正则表达式将行分成三部分,然后使用SimpleUnsortedWriter(由 Cassandra 提供)将其作为键、列和值写入某个文件。处理完 16MB 数据后,它会刷新到磁盘。

但是所有文件的处理逻辑都是相同的,即使是一个大小为 330MB 但少于 100 万行的文件在 30 秒内得到处理。可能是什么原因?

deviceWriter = new SSTableSimpleUnsortedWriter(
        directory,
        keyspace,
        "Devices",
        UTF8Type.instance,
        null,
        16);

Pattern pattern = Pattern.compile("[\\[,\\]]");
while ((line = br.readLine()) != null)          
{
    //split the line i n row column and value
    long timestamp = System.currentTimeMillis() * 1000;
    deviceWriter .newRow(bytes(rowKey));
    deviceWriter .addColumn(bytes(colmName), bytes(value), timestamp);

}

已经改变了-Xmx256M to -Xmx 1024M,但无论如何它都没有帮助。

更新: 根据我的观察,当我写入缓冲区(在物理内存中)时,没有。写入缓冲区的次数正在增加,较新的写入需要时间。(这是我的猜测)

请回复。

4

4 回答 4

5

唯一要做的BufferedReader就是从底层读取Reader到默认大小为 8K 的内部char[]缓冲区,所有方法都在该缓冲区上工作,直到它耗尽,此时从底层读取另一个 8K(或其他)Reader。这readLine()是一种附加的。

正确使用BufferedReader绝对不会导致运行时间从 1.8m 线的 40 秒上升到 3m 线的 30 分钟。你的代码一定有问题。展示给我们看。

另一种可能性是您的 JVM 没有足够的堆内存并花费 30 分钟的大部分时间进行垃圾收集,因为它的堆已满 99%,您最终会获得OutOfMemoryError更大的输入。您对已处理的行做了什么?它们是否保存在记忆中?-Xmx 1024M使用命令行选项运行程序会有所不同吗?

于 2011-08-24T17:11:56.167 回答
1

BufferedReader 不会查找,它只是缓存字符,直到找到换行符并将该行作为字符串返回,在每一行之后丢弃(重用)缓冲区。这就是为什么您可以将它与任何流或其他阅读器一起使用,即使是那些不支持搜索的阅读器。

因此,仅行数不应该在读者层面产生如此大的差异。然而,很长的行可能会创建一个非常大的字符串并分配大量 RAM,但这似乎不是您的情况(在这种情况下,它可能会因超过 GC 时间或类似情况而引发 OutOfMemory 异常)。

对于我在您的代码中看到的内容,您没有做错任何事情。我想你正在达到某种限制,因为它似乎不是 RAM,也许它与 Cassandra 方面的一些硬限制有关?您是否尝试过注释掉写在 Cassandra 上的部分?只是看看是你的一方还是 Cassandra 一方导致了问题。

于 2011-08-24T17:03:49.343 回答
1

查看 NIO Buffered,因为它们比 BufferReader 更优化。

来自另一个论坛的一些代码片段。http://www.velocityreviews.com/forums/t719006-bufferedreader-vs-nio-buffer.html

FileChannel fc = new FileInputStream("File.txt").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
fc.read(buffer);

编辑:也看看这个线程Read large files in Java

于 2011-08-24T17:05:25.467 回答
1

BufferedReader可能不是您的性能问题的根源。

根据您引用的数字,听起来您的代码中有一些二次复杂度。例如,对于您阅读的每一行,您都在重新检查您之前阅读过的每一行。我只是在这里推测,但问题的一个常见示例是使用列表数据结构,并检查新行是否与之前的任何行匹配。

于 2011-08-24T17:29:31.657 回答