在 Java 的一行中对多个整数使用 BufferedReader 而不是 Scanner Class 是否最佳?

Is it optimal to use BufferedReader instead of Scanner Class for multiple integers on a single line in Java?

As buffered reader 在用户输入值的情况下比 scanner class 快得多,但是正如在大多数算法竞赛或面试中观察到的那样,通常有多个整数在单个输入线上。因此,使用 Scanner Class -

变得更容易
    Scanner in=new Scanner(System.in);
    int a=in.nextInt();
    int b=in.nextInt();

如果是Buffered Reader,则必须先输入一行(因为没有readInt选项),然后根据其上的整数个数解析该行-

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int a,b;
    String line = br.readLine(); 
    String[] strs = line.trim().split("\s+");
    a=Integer.parseInt(strs[0]);
    b=Integer.parseInt(strs[1]);

虽然后一种情况下输入可能会更快,但是解析会不会花费很多时间将得到的字符串分成一个个整数? 因此,在这种情况下,以上哪一项更优或更快?

谢谢。

非常错误的方法:你在谈论用户输入如何处理人类时间尺度上提供的内容绝对无关紧要。

人类在 "seconds" 上操作,在某些情况下 "milli seconds"。

而就 性能 而言,Scanner 和 BufferedReader 之间的差异可能在 micro 秒的范围内,甚至可能 纳米秒.

即使我们不谈论人类在控制台上输入内容(但使用 管道,如 cat somefile | java Whatever)——你仍然有 IO 大规模发生。您的应用程序将花费 99.99% 的时间等待 IO 发生。传入的字符串最终如何处理根本无关紧要。

换句话说:你最好把时间花在编写 干净 代码上,这样可以以一种易于理解的直接方式完成工作 human 读者。然后让 JIT 发挥它的魔力。

因为这个问题是专门关于处理 "file based" 输入的 - 你自己去 profile 。我会在这里做什么:

  • 创建一个抽象层,让我轻松在不同的实现之间切换
  • 那我就开始benchmark不同的解决方案(仔细阅读this为这样的activity做准备)

你看,最终两个段代码会做非常相似的事情。 Scanner 还在做 something,你必须花相当长的时间去研究相应的源代码,才能理解 Scanner 解析和 BufferedReader 读取 + 手动解析之间的潜在差异。

这是代码清晰度比速度更重要的情况之一。

很容易看出使用 Scanner 的代码直截了当,读起来很自然。

另一方面,使用 BufferedReader 的代码在执行需要执行的操作(从输入中读取两个整数)之前会执行一些额外的任务,因此 reader 的代码可能会花费几秒钟看看发生了什么。

当然,两种实现都缺少一些错误处理代码。例如,第二个实现需要检查 split 是否恰好返回了两个项目。如果第一个实现忽略所有错误检查,调用者将收到一条消息,指出输入中没有整数。第二种实现会得到一个索引超出范围的异常,这将需要额外的研究来了解发生了什么。

就解析而言,它必须在两种情况下都发生,因此您最终会花费大约相同数量的 CPU 周期来处理它。