Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

As buffered reader is much faster than scanner class in case of inputting values from the user, however as observed in most of the Algorithm Competitions or in case of interviews there are often multiple integers on a single input line. Hence, it becomes easier to use Scanner Class -

    Scanner in=new Scanner(System.in);
    int a=in.nextInt();
    int b=in.nextInt();

In case of Buffered Reader, you will have to first input a line (as there is no option of readInt) and then parse the line according to number of integers on it -

    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]);

Although the input may be faster in latter case, won't the parsing take up much time to divide the obtained string into indiviual integers? Hence, in such case which one of the above is more optimal or faster?

Thank you.

like image 745
user8321763 Avatar asked Jan 30 '23 14:01

user8321763


2 Answers

Very wrong approach: you are talking about user input. It absolutely doesn't matter how you process something that is provided on human time scale.

A human operates on "seconds", in some scenarios on "milli seconds".

Whereas the delta between a Scanner and a BufferedReader in terms of performance is probably in the range of micro seconds, maybe even nano seconds.

And even when we don't talk about a human person typing in content on the console (but using piping, like cat somefile | java Whatever) - you still have IO happening on a large scale. Your application will spent 99.99% of its time waiting for IO to happen. How the incoming strings are processed in the end simply doesn't matter.

In other words: you better spent your time on writing clean code, that gets the job done in a straight forward way that is easy to understand to its human readers. And then let the JIT do its magic.

As the question is specifically about processing "file based" input - go profile yourself. What I would do here:

  • create an abstraction layer that allows me to easily switch between different implementations
  • then I would start to benchmark different solutions (carefully read this to prepare for such activity)

You see, in the end both pieces of code will do very similar things. A scanner is still working on something, and you would have to dig into the corresponding source code for quite some time to understand potential differences between Scanner parsing and BufferedReader reading + manual parsing.

like image 149
GhostCat Avatar answered Feb 02 '23 10:02

GhostCat


This is one of the cases when code clarity is more important than the speed.

It is easy to see that the code using Scanner goes strait to the point of what is going on, and reads very naturally.

On the other hand, the code using BufferedReader performs some additional tasks before doing what it is required to do (reading two integers from the input) so a reader of your code may spend a few seconds to see what is going on.

Of course, some error handling code missing from both implementations. For example, the second implementation needs to check that split returned exactly two items. If the first implementation omits all error checking, the caller would get a message saying that there's no integer in the input. The second implementation would get an index out of range exception, which would require additional research to see what is going on.

As far as the parsing goes, it has to happen in both cases, so you would end up spending about the same number of CPU cycles to process it.

like image 24
Sergey Kalinichenko Avatar answered Feb 02 '23 10:02

Sergey Kalinichenko