我正在寻找最省时的方式逐行读取STDIN。

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

我已经尝试了以下方法(加上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++;
    }
    
  • 结果:
  • 3228ms扫描仪,而
  • 2264ms用于扫描仪,而
  • 1309ms用于扫描仪,而
  • 扫描仪时为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++;
    }
    
  • 结果:
  • 3168ms用于
  • 的扫描仪
  • 2207ms用于
  • 的扫描仪
  • 1236ms用于
  • 的扫描仪
  • 467ms扫描仪,用于
  • 带有循环的
  • 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());
    

    }
  • 结果:
  • 3273ms用于
  • 的bufferreader
  • 2330ms用于
  • 的bufferreader
  • 1293ms用于
  • 的bufferreader
  • 507ms用于
  • 的bufferreader
    带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());
    

    }
  • 结果:
  • 3296ms用于bufferreader,而
  • 2358ms用于bufferreader,而
  • 1307ms用于bufferreader,而
  • 500ms用于bufferreader,而

  • 在调试所花费的时间时,我注意到每次读取后所花费的时间都会减少。
    是否可以限制已初始化的字节(例如:如果您最多有100.000个字符,请将扫描器/缓冲读取器限制为仅初始化100 000个字符。读取后,需要用接下来的100 000个字符重新填充自身)

    关于此事的任何想法都值得欢迎。

    编辑:添加了每种情况下的代码以及每行读取所花费的时间。也将100.000更改为100000以更容易阅读。

    最佳答案

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

  • 它使用StringBuffer代替StringBuilder,这会产生同步开销。
  • 似乎还有数据复制开销-不能完全确定,最好检查一下。
  • BufferedReader中的专用监视对象,甚至更多的同步开销。

  • 您可能会碰到两件事:
  • 编写您自己的缓冲,这样可以节省两次数据复制的时间。
  • 编写您自己的nextLine方法,该方法将使用StringBuilder并以简单的循环遍历源数据。
  • 10-06 01:59