在Java中阅读 System.in 的最快方法是什么?

2022-08-31 14:46:49

我正在阅读一堆整数,这些整数由空格或换行符分隔,与使用.Scanner(System.in)

在Java中有什么更快的方法来做到这一点吗?


答案 1

在Java中有什么更快的方法来做到这一点吗?

是的。扫描仪相当慢(至少根据我的经验)。

如果您不需要验证输入,我建议您只需将流包装在BufferedInputStream中,并使用类似 / .String.splitInteger.parseInt


一个小小的比较:

使用此代码读取 17 MB(4233600 个数字)

Scanner scanner = new Scanner(System.in);
while (scanner.hasNext())
    sum += scanner.nextInt();

在我的机器上花了3.3秒。而此片段

BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = bi.readLine()) != null)
    for (String numStr: line.split("\\s"))
        sum += Integer.parseInt(numStr);

花了0.7秒

通过进一步搞砸代码(用/迭代),你可以很容易地把它减少到大约0.1秒,但我认为我已经回答了你的问题,我不想把它变成一些代码高尔夫。lineString.indexOfString.substring


答案 2

我创建了一个小型的 InputReader 类,它的工作方式与 Java 的 Scanner 类似,但在速度上优于它很多数量级,事实上,它的性能也优于 BufferedReader。下面是一个条形图,它显示了我创建的 InputReader 类的性能,该类从标准输入读取不同类型的数据:

enter image description here

以下是使用 InputReader 类查找来自 System.in 的所有数字之和的两种不同方法:

int sum = 0;
InputReader in = new InputReader(System.in);

// Approach #1
try {

    // Read all strings and then parse them to integers (this is much slower than the next method).
    String strNum = null;
    while( (strNum = in.nextString()) != null )
        sum += Integer.parseInt(strNum);

} catch (IOException e) { }

// Approach #2
try {

    // Read all the integers in the stream and stop once an IOException is thrown
    while( true ) sum += in.nextInt();

} catch (IOException e) { }

推荐