-3

I've been working on a project to show that reading input using Scanner is slower than using buffered reader which is in turn is slower than using our own functions which parse integer using suitable manipulation. For this I'm noting down the execution time to read input in each case.

long startTime,endTime,duration;

startTime=System.nanoTime();
/* Reading input via scanner */     
endTime=System.nanoTime();
duration = endTime - startTime;
System.out.println(duration); 

startTime=System.nanoTime();
/* Reading input via buffered reader */     
endTime=System.nanoTime();
duration = endTime - startTime;
System.out.println(duration); 

startTime=System.nanoTime();
/* Reading input via own function for I/O */     
endTime=System.nanoTime();
duration = endTime - startTime;
System.out.println(duration); 

I'm getting runtime error in above code if I try running all three in a single program. However, if I use one method at a time, it works fine. I doubt there's some problem in my way to compute execution time. Please help.

Here's my code http://ideone.com/BwvAXr

CPPCoder
  • 155
  • 1
  • 1
  • 10
  • 2
    Could you post the stack trace? And the code you put in comments is probably the source of the problem. Please post that as well. – bknopper Mar 02 '14 at 12:25
  • 2
    It's difficult to help if you won't tell us what the error is. – kdgregory Mar 02 '14 at 12:26
  • Looks to me like the error come from the code that reads the input. Are you reading from `stdin` or do you open a file? Do you use a separate file reader for each method? If so, how do you open it, and do you remember to close it? – Idan Arye Mar 02 '14 at 12:28
  • http://ideone.com/BwvAXr – CPPCoder Mar 02 '14 at 12:32
  • Above is the link to my code – CPPCoder Mar 02 '14 at 12:34
  • I've posted the link to my code above. – CPPCoder Mar 02 '14 at 12:39
  • stderr Exception in thread "main" java.util.InputMismatchException at InputReader.read(Main.java:56) at InputReader.readInt(Main.java:73) at Main.main(Main.java:31) – CPPCoder Mar 02 '14 at 12:40
  • The code you've linked to on ideone.com does not contain the section of code for reading via the BufferedReader. As a result I cannot reproduce a problem when running it. I can only guess that your BufferedReader reads from `System.in`, and after you use the BufferedReader, you close it, which closes `System.in`. Therefore your third test fails because it attempts to read from a closed stream. In the absence of any code that reproduces your error, I can say no more. – Luke Woodward Mar 02 '14 at 12:47
  • 1
    Uhm, it's you who wrote the code throwing the `InputMismatchException`: `if (c < '0' || c > '9')`. So just fix it according to your needs. – home Mar 02 '14 at 12:49
  • @Lukewood But even in the absence of buffered reader,.. when I' using only the other two methods, its giving runtime error as was shown in the link to my code above – CPPCoder Mar 02 '14 at 12:51
  • @Home http://ideone.com/8VKIhK Class definition is working fine. – CPPCoder Mar 02 '14 at 12:54

1 Answers1

1

Your code assumes that the Scanner has only consumed as much of the input stream that it actually needs. However, it seems that the scanner is actually buffering the input. In other words, by the time you try to read the second line of input using your InputReader, the Scanner has already read it from standard input and stored it in a buffer. So when your InputReader attempts to read from standard input, there's no data to read.

Your code that uses the BufferedReader quite probably makes the same assumption.

It would be better to use separate input streams for each test, rather than sharing a stream. That way you don't have to worry about how much data was read from a stream by one reader before you pass it to the next reader. System.in isn't a good choice for this, as there's only one of them. It would be better to use a stream such as ByteArrayInputStream, which creates an InputStream from a byte array. For example, you could use a method such as the following to create a stream for test purposes:

    // Add this to your Main class.
    private static InputStream getTestStream() {
        return new ByteArrayInputStream("1 2 3 4 5 6 7 8 9 10".getBytes(Charset.forName("UTF-8")));
    }

You would then set up your Scanner and InputReader (and also a BufferedReader) using a call to this method:

    InputReader in = new InputReader(getTestStream());
    // ...
    Scanner sc=new Scanner(getTestStream());

I made these changes to your code and it ran successfully.

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104