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);