Faster Input for Java

Problem: Scanner is Slooooow

Using Scanner to parse input is convenient, but too slow. Using BufferedReader and StringTokenizer is much faster, but its a lot of typing during a competition. Can we make Java easier for the ACM ICPC?

Too much typing in Java (and worse if you use BufferedReader)
Java C/C++
 Scanner input =
    new Scanner(;
 double x = input.nextDouble();
 double x;

How Slow?

I ran some tests to read 10,000,000 int or double from a file. Times are shown in the tables below. I ran the tests on an Intel Core2 Duo 2.4GHz cpu with Windows XP Pro SP3, Sun JDK 6.0r22, and GNU gcc 4.5.2.

Table 1. Time to read 10,000,000 int values from file
Input Method Time (sec)
C scanf("%d", &arg) 3.78
Scanner.parseInt() 29.52
BufferedReader + inline Integer.parseInt 2.89
BufferedReader + Reader.nextInt method 3.01

Table 2. Time to read 10,000,000 double values from file
Input Method Time (sec)
C scanf("%lf", &arg) 11.9
Scanner.parseDouble() 66.86
BufferedReader + inline Double.parseDouble 3.06
BufferedReader + Reader.nextDouble method 3.14

Listing 1. Sample methods to read using Scanner and BufferedReader. We split the input line into string tokens, since one line may contain multiple values. To split the input, StringTokenizer is 4X faster than string.split().
 /** Read count integers using Scanner */
 static int scanInteger(int count) {
    Scanner scanner = new Scanner(input);
    int last = 0;
    while (count-- > 0) {
	    last = scanner.nextInt();
    return last;
 /** Read count integers using BufferedReader */
 static int readIntegers(int count) 
        throws IOException {
    BufferedReader reader = new BufferedReader(
               new InputStreamReader(input) );
    StringTokenizer tokenizer = new StringTokenizer("");
    int last = 0;
    while (count-- > 0) {
        if (! tokenizer.hasMoreTokens() ) {
            tokenizer = new StringTokenizer(reader.readLine());
        last = Integer.parseInt(tokenizer.nextToken());
    return last;

Creating Reusable Code

How to reduce the burden of reading input in Java? Java has some advantages over C/C++: fewer syntax errors, maybe fewer logic errors, good code generation and debugger in Eclipse.

To make Java easier to use, let's put the reader code in a separate class. (You can put many classes in one source file, provided that only one class is "public".) We can copy-and-paste our Reader class into every ACM task, so we only have to write it once during competition. One person can write it while the others study the problems.

Listing 2 is an example. Let me know if you find any short, more efficient code. I use StringTokenizer instead of string.split() because StringTokenizer is much faster. I use static methods so we don't have to create or keep track of a "Reader" object, and use the default (package) scope so I don't have to type "public".

Putting the input methods in a separate class has almost no effect on the speed (kind of surprising), in my benchmark. But it does make our code more reusable and simplifies the rest of your task code.

Its still a lot of code, but after you type it once you can copy-paste into every task.

So in your ACM tasks you can write:

     Reader.init( );
     double x = Reader.nextDouble();
     int n = Reader.nextInt();

Listing 2. Reusable class for reading int and double.
/** Class for buffered reading int and double values */
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        return tokenizer.nextToken();

    static int nextInt() throws IOException {
        return Integer.parseInt( next() );
    static double nextDouble() throws IOException {
        return Double.parseDouble( next() );