Java 使用BufferedReader时性能低下
我正在使用Java 使用BufferedReader时性能低下,java,text-processing,readline,bufferedreader,seek,Java,Text Processing,Readline,Bufferedreader,Seek,我正在使用BufferReader.readlLine()逐行处理大量文本文件 两个文件大小相同,为130MB,但其中一个需要40秒处理,而另一个需要75秒处理 我注意到一个文件有180万行,而另一个文件有210万行。但当我试图处理一个300万行大小相同的文件时,需要30分钟来处理 所以我的问题是: 这种行为是因为缓冲区读取器的寻道时间(我想知道BufferedReader是如何逐行工作或解析文件的?) 有什么方法可以让我以更快的方式逐行读取文件吗 好的,朋友们,我将提供更多的细节 我使用正则表
BufferReader.readlLine()
逐行处理大量文本文件
两个文件大小相同,为130MB,但其中一个需要40秒处理,而另一个需要75秒处理
我注意到一个文件有180万行,而另一个文件有210万行。但当我试图处理一个300万行大小相同的文件时,需要30分钟来处理
所以我的问题是:
BufferedReader
是如何逐行工作或解析文件的?)SimpleUseredWriter
(由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更改为-Xmx 1024M
,但无论如何都没有帮助
更新:根据我的观察,当我写入缓冲区(在物理内存中)时,随着写入缓冲区的次数增加,新的写入需要时间。(这是我的猜测)
请回复。BufferedReader不会搜索,它只是缓存字符,直到找到换行符,并将该行作为字符串返回,在每行之后丢弃(重用)缓冲区。这就是为什么您可以将它用于任何流或其他阅读器,即使是那些不支持查找的阅读器 因此,单是行数不应该在读者层面造成如此大的差异。然而,一个很长的行可能会创建一个很大的字符串并分配大量的RAM,但这似乎不是您的情况(在这种情况下,它可能会抛出一个超出GC时间或类似情况的OutOfMemory异常)
从你的代码中我可以看出,你没有做错任何事。我想你正在达到某种极限,因为它似乎不是RAM,也许它与卡桑德拉方面的硬极限有关?你试过评论卡桑德拉的那部分吗?看看是您的方面还是Cassandra方面导致了问题。查看NIO Buffered,因为它们比BufferReader更优化 来自另一个论坛的一些代码片段
编辑:也查看这个线程,
BufferedReader
所做的唯一事情就是从底层的读取器
读入一个默认大小为8K的内部char[]
缓冲区,所有方法都在该缓冲区上工作,直到它耗尽为止,此时再读入一个8K(或其他任何值)从基础读取器
读取。readLine()
正确使用BufferedReader
绝对不会导致运行时间从1.8m线路的40秒上升到3m线路的30分钟。你的代码一定有问题。给我们看看
另一种可能性是,JVM没有足够的堆内存,并将30分钟的大部分时间用于垃圾收集,因为它的堆已满99%,并且最终会得到一个带有较大输入的OutOfMemoryError
。您对已处理的行做了什么?它们被保存在记忆中吗?使用-Xmx 1024M
命令行选项运行程序是否会有所不同?BufferedReader
可能不是性能问题的根源
根据您引用的数字,您的代码似乎有一些二次复杂性。例如,对于您阅读的每一行,您都在重新检查之前阅读的每一行。我只是在这里推测一下,但一个常见的问题示例是使用列表数据结构,并检查新行是否与以前的任何行匹配。请发布使用BufferReader的代码,因为它不必与BufferedReader一起使用,但是随着你对每一行的处理。嘿,谢谢…提供了关于我的问题的更多细节,请继续through@samarth当前位置我看不出你发布的代码有任何问题。最简单的解决方案可能是使用VisualVM进行一些简单的评测。这应该会告诉你所有的时间都花在了哪里,这可能会直接引导你找到问题的原因。嘿,谢谢…提供了有关我问题的更多详细信息,请浏览hey,谢谢…提供了有关我问题的更多详细信息,请浏览hey,谢谢…提供了有关我问题的更多详细信息,请浏览
FileChannel fc = new FileInputStream("File.txt").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
fc.read(buffer);