【问题标题】:How can I improve the speed of reading big-size file in Java?如何提高 Java 读取大文件的速度?
【发布时间】:2013-08-10 09:57:27
【问题描述】:

我刚刚读取了一个大小为167MB,行号为1884000的文件。我使用的方法是BufferedReader,得到了一行读取的效果。

我注意到,随着当前行号的增加,读取文件的过程越来越慢(在这种情况下,我花了 3h30min 来完成它)。

我知道使用nio 可能会加快这个过程,但我想直接读取文件。

我的代码如下;谁能给我一些建议?非常感谢!

String htmlContentPath = html.getAbsolutePath();
BufferedReader reader = new  BufferedReader(new InputStreamReader(new FileInputStream(htmlContentPath)));
String line = null;
int cnt = 0;
while((line = reader.readLine()) != null)       {
    this.proc(line);
    if((cnt++ % 2000) == 0) {
        logger.info("current line number:\t"+cnt);
    }
}

【问题讨论】:

  • proc(line) 是做什么的?运行时间越长,它会减慢速度吗?
  • 每次迭代都需要调用this.proc(line) 吗?
  • 1.使用多个线程 2. 正确同步线程 3. 使用 Java NIO Channels :)
  • 您没有使用 FileReader 有什么原因吗?
  • 即使阅读速度很慢,我也能达到 100 MB/s vanillajava.blogspot.co.uk/2011/01/… 我怀疑不是阅读,而是你对文本的处理速度很慢。

标签: java java-io


【解决方案1】:

对我来说,这听起来像是一个内存问题(由于内存不足,垃圾收集的需求增加,速度通常会变慢)。

您发布的代码看起来不应该随着行号的增加而变慢(假设 proc() 调用是“干净的”)。

我第二次 Chris G 建议删除 proc() 调用,以查看当您只是阅读罚款而不处理任何行时是否仍然会出现减速。

我还要补充一点,您可以尝试使用 -Xmx 和 -Xms 标志让 JVM 一开始就可以访问更多内存。

这是一个可能相关的问题:Java threads slow down towards the end of processing

【讨论】:

    【解决方案2】:

    当我第一次阅读您的问题时,我打算建议您注释掉对 proc() 的调用,然后使用其他一些答案来加快文件的读取速度(这应该是整个执行时间,因为您评论了处理调用)。

    进一步考虑,我建议您使用分析器(没有注释掉任何行) .分析器可以向您显示代码中的热点——您似乎大部分时间都在的地方。这些信息,加上您对程序逻辑的了解,将有助于加快最严重的瓶颈。

    这是一个迭代过程,结果越来越好。

    我还建议您首先使用小得多的示例文件进行测试。

    【讨论】:

    • @Ivan。我确定。我只知道 Eclipse,但分析是一个非常重要的功能,您可以在任何 IDE 上找到它。不考虑 NetBeans 或 IntelliJ 的意图。
    【解决方案3】:

    你应该可以在这里找到答案:

    http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly

    为了获得最佳的 Java 读取性能,需要记住以下四点:

    • 通过一次读取一个数组而不是一次读取一个字节来最小化 I/O 操作。一个 8Kbyte 的数组是一个不错的大小。

    • 通过一次获取一个数组而不是一次获取一个字节来最小化方法调用。使用数组索引来获取数组中的字节。

    • 如果您不需要线程安全,请尽量减少线程同步锁。要么减少对线程安全类的方法调用,要么使用非线程安全类,如 FileChannel 和 MappedByteBuffer。

    • 尽量减少 JVM/OS、内部缓冲区和应用程序阵列之间的数据复制。将 FileChannel 与内存映射或直接或包装数组 ByteBuffer 一起使用。

    【讨论】:

    • 他正在通过BufferedReader 阅读台词,这已经满足了你的前两点。
    【解决方案4】:

    这可能是由交换引起的,根据 proc 方法中文件的内存占用情况,您可以在进程上执行 visualVM 以查看堆状态,然后调整 (xms, xmx)/减少内存消耗你的方法。

    干杯。

    【讨论】:

      猜你喜欢
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 1970-01-01
      • 2015-06-15
      • 2019-06-22
      相关资源
      最近更新 更多