逐行阅读STDIN的最快方式?

我正在寻找最经济有效的逐行读取STDIN的方法。

第一行是要测试的条件数。 以下所有行都是条件(字符串),最多为100 000个字符。

我已经尝试过以下内容(加上4次90 000个字符的结果:

  • 带有while循环的扫描仪(7255 ms)

    Scanner sc = new Scanner(System.in); int numberOfLines = Integer.parseInt(sc.nextLine()); long start = 0; int i = 1; while (i<=numberOfLines){ start = System.currentTimeMillis(); sc.nextLine(); Debug.println((System.currentTimeMillis()-start) + "ms for scanner while"); i++; } 
    • 结果:
      1. 扫描仪3228ms
      2. 扫描仪2264ms
      3. 扫描仪1309ms
      4. 扫描仪454ms
  • 带有for循环的扫描仪(7078 ms)

     Scanner sc = new Scanner(System.in); int numberOfLines = Integer.parseInt(sc.nextLine()); long start = 0; for (int i = 1; i<= numberOfLines;i++){ start = System.currentTimeMillis(); sc.nextLine(); Debug.println((System.currentTimeMillis()-start) + "ms for scanner for"); //i++; } 
    • 结果:
      1. 3168毫秒扫描仪
      2. 2207ms用于扫描仪
      3. 用于扫描仪的1236毫秒
      4. 用于扫描仪的467毫秒
  • 带有for循环的BufferedReader(7403 ms)

     try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int numberOfLines = Integer.parseInt(br.readLine()); long start = 0; for (int i = 0; i< numberOfLines;i++){ start = System.currentTimeMillis(); br.readLine(); Debug.println((System.currentTimeMillis()-start) + "ms for bufferreader for"); //i++; } } catch (Exception e) { System.err.println("Error:" + e.getMessage()); 

    }

    • 结果:
      1. 缓冲区读取器为3273ms
      2. 2330ms用于缓冲区读取器
      3. 缓冲区读取器为1293ms
      4. 缓冲区读取器为507ms
  • 具有while循环的BufferedReader(7461 ms)

     try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int numberOfLines = Integer.parseInt(br.readLine()); int i=0; long start = 0; while(i< numberOfLines){ start = System.currentTimeMillis(); br.readLine(); Debug.println((System.currentTimeMillis()-start) + "ms for bufferreader while"); i++; } } catch (Exception e) { System.err.println("Error:" + e.getMessage()); 

    }

    • 结果:
      1. 缓冲区读取器为3296ms
      2. 缓冲区读取器为2358ms
      3. 缓冲区读取器为1307ms
      4. 缓冲区读取器500ms

在调试所花费的时间时,我注意到每次读取后所花费的时间减少了。 是否可以限制初始化的字节数(fe:如果最多有100.000个字符,则限制扫描器/缓冲读取器仅初始化100 000个字符。读取后需要重新填充下一个100 000个字符)

关于这个问题的任何想法都非常受欢迎。

编辑:添加每个方案的代码以及每行读取的时间。 也更改了100.000到100 000更容易阅读。

查看BufferedReader#readLine源代码。 我看到几个问题:

  1. 它使用StringBuffer而不是StringBuilder,这会产生同步开销。
  2. 此外,似乎有数据复制开销 – 不完全确定,更好地检查出来。
  3. BufferedReader中的专用监视器对象以及更多的同步开销。

你可以用两件事来抓住机会:

  1. 编写自己的缓冲,这可以节省一些时间来复制数据。
  2. 编写自己的nextLine方法,该方法将使用StringBuilder并以简单的周期检查源数据。