什么是Java中用来计算以大文件中的String开头的行的最快方式

时间:2017-03-22 18:17:20

标签: java performance file file-io

我有大文件(每个4.5 GB),需要计算每个文件中以给定标记开头的行数。每个文件最多可以出现200k个令牌。

实现如此庞大的文件遍历和字符串检测的最快方法是什么?使用ScannerString.startsWith()

是否有比使用以下实现更有效的方法
public static int countOccurences(File inputFile, String token) throws FileNotFoundException {
    int counter = 0;
    try (Scanner scanner = new Scanner(inputFile)) {
        while (scanner.hasNextLine()) {
            if (scanner.nextLine().startsWith(token)) {
                counter++;
            }
        }
    }
    return counter;
}

注意:

  • 到目前为止看起来Scanner是瓶颈(即如果我添加比令牌检测更复杂的处理并将其应用于所有行,则整体执行时间或多或少相同。)
  • 我使用的是SSD,因此硬件方面没有改进的余地

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

一些指针(假设线条相对较短且数据实际上是ASCII或类似的):

  • 一次读取一个巨大的字节缓冲区(比如1/4 GB),然后切断不完整的行以预先添加到下一个读取。

  • 搜索字节,不要浪费时间转换为字符

  • 通过'\ n'开始搜索模式表示“行首,专门处理第一行

  • 使用高速搜索,以牺牲预处理为代价缩短搜索时间(google用于“快速子字符串搜索”)

  • 如果需要实际的行号(而不是行),请在单独的阶段计算行数

答案 1 :(得分:1)

我们可以减少在字节流中搜索\n<token>的问题。在这种情况下,一种快速的方法是从磁盘顺序读取一大块数据(大小是根据经验确定的,但一个好的起点是1024页),并将该数据交给另一个线程进行处理。