关于性能:在Java中计算以大文件中的String开头的行的最快方式是什么

What's the fastest way in Java to count lines starting with a String in a huge file

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

什么是实现如此巨大的文件遍历和字符串检测的最快方法? 使用ScannerString.startsWith()是否有比以下实现更有效的方法?

1
2
3
4
5
6
7
8
9
10
11
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,因此硬件方面没有改进的余地

在此先感谢您的帮助。


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


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

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

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

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

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

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