Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5067317

java.util.Scanner should cache results of hasNextLine

XMLWordPrintable

    • b25
    • x86
    • windows_xp

      Name: jl125535 Date: 06/23/2004


      FULL PRODUCT VERSION :
      java version "1.5.0-beta3"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta3-b56)
      Java HotSpot(TM) Client VM (build 1.5.0-beta3-b56, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      The code to sum a column of Integers (400 000) using java.util.Scanner
      is 10 times slower than it's JDK1.4 counterpart
      (with BufferedReader.readLine() and Integer.parseInt()).

      I think this performance problem is a serious handicap to
      the scanner adoption.

      I see at least one optimisation.
      It is not necessary to create an intermediary string,
      the code of Integer.parseInt() could be written using
      a CharSequence.




      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      generate a text file
      C:\eclipse\workspace\bits>java -cp classes15 LineGenerator > test.txt

      run the two programms :
      C:\eclipse\workspace\bits>java -cp classes15 AddLine2 < test.txt
      C:\eclipse\workspace\bits>java -cp classes15 AddLine < test.txt

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      >java -cp classes15 AddLine2 < test.txt
      -1604578624
      (a number near 343108971)

      >java -cp classes15 AddLine < test.txt
      -1604578624
      343108971

      ACTUAL -
      >java -cp classes15 AddLine2 < test.txt
      -1604578624
      3192452393

      >java -cp classes15 AddLine < test.txt
      -1604578624
      343108971

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      AddLine:
      import java.io.*;
      import java.util.*;

      public class AddLine {
        public static void main(String[] args) throws IOException{
          long time=System.nanoTime();
          
          int sum = 0;
          String line;
          
          BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
          while ((line = in.readLine()) != null) {
            sum = sum + Integer.parseInt(line);
          }
          System.out.println(sum);
          
          System.out.println(System.nanoTime()-time);
        }
      }


      AddLine2:
      import java.util.*;

      public class AddLine2 {
        public static void main(String[] args) {
          long time=System.nanoTime();
         
          int sum = 0;
          Scanner scanner=new Scanner(System.in);
          while (scanner.hasNextInt()) {
            sum = sum + scanner.nextInt();
          }
          System.out.println(sum);
          
          System.out.println(System.nanoTime()-time);
        }
      }


      LineGenerator:
      public class LineGenerator {
        public static void main(String[] args) {
          for(int i=0;i<400000;i++)
            System.out.println(i);
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      don't use java.util.Scanner
      (Incident Review ID: 280992)
      ======================================================================
      ###@###.### 11/1/04 20:33 GMT

            sherman Xueming Shen
            jleesunw Jon Lee (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: