Fast I/O In Java For Competitive Programming

Fast I/O In Java For Competitive Programming
Fast I/O In Java For Competitive Programming

Introduction

If you are someone participating regularly in programming contests, then this article will guide you to minimize your time by writing fast I/O in Java. In any contest, It is very important to use the fast I/O operations to make things faster for you and can help you achieve better ranks.

Moreover, if you are using Java for your problem solving then it becomes very important to use the best method for I/O as Java is slow in comparison to C++.

In this article, we will discuss different methods for I/O in java to find the fastest way that is best suited for competitive programming and will help you change your verdict from TLE to AC.

To see the time and space taken by each method we will solve the “Division by Four” problem using each method on CodeStudio. In this problem, we will be given N integers and we need to update each element in the array with the quotient generated upon division by 4. In case the quotient turns out to be 0 for any “arr[i]”, we update “arr[i]” to -1.

Following are the methods for I/O in java, with a measure of runtime in milliseconds for each method. However, the execution time may vary with different servers for each of the methods but this will help you compare the performance of each method.

Scanner Class

Scanner class is one of the easiest ways to take input in java and requires less typing but at the same time, it is one the slowest method to take input.It uses inbuilt methods like nextInt(),nextDouble(),nextLong() to read input.

It is initiated with the input stream like System.in. It is one of the most inefficient methods and should be avoided in competitive programming.

Code:

// program using Scanner
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
	public static void main(String[] args)
	{
		Scanner s = new Scanner(System.in);
          int n = s.nextInt();
    		int[] array = new int[n];
    		for(int i=0;i<n;i++)
    		{
    		    array[i]= s.nextInt();
    		}
    		for(int i=0;i<n;i++)
    		{
    		    if(array[i]/4>0)
    		    {
    		        array[i]=array[i]/4;
    		    }
    		    else
    		    {
    		        array[i]=-1;
    		    }
    		}
    		
    	   for(int i=0;i<n;i++)
    	   {
    	       System.out.print(array[i]+" ");
    	   }
         System.out.print("\n");
         
		
	}
}

The runtime for the above code is:

If you want to explore Scanner a little more in specific, check out our blog on “Scanner Class in Java”.

BufferedReader

BufferedReader class reads text from the character input stream. It provides an efficient reading of characters as it buffers the characters. It is faster in comparison to the Scanner class. while using the BufferedReader class every time we need to parse the value to the desired type.

Reading multiple elements from a single line adds to its complexity due to the use of Stringtokenizer. But the problem with this method is that it requires a lot of typing which can be a problem while taking part in a contest where speed matters.

Code:

// program using BufferedReader
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    public static void main(String[] args)
        throws IOException
    {
 
        BufferedReader br = new BufferedReader(
            new InputStreamReader(System.in));
           
            {
               
                
                StringTokenizer st
                    = new StringTokenizer(br.readLine());
        		int n=Integer.parseInt(st.nextToken());
        		int[] array = new int[n];
        		
        		for(int i=0;i<n;i++)
        		{
        		    array[i]= Integer.parseInt(st.nextToken());
        		}
        		for(int i=0;i<n;i++)
        		{
        		    if(array[i]/4>0)
        		    {
        		        array[i]=array[i]/4;
        		    }
        		    else
        		    {
        		        array[i]=-1;
        		    }
        		}
        	   for(int i=0;i<n;i++)
        	   {
        	       System.out.print(array[i]+" ");
        	   }
                System.out.print("\n");
        }
 
  }
}

The runtime for the above code is:

Notice how by using this method the runtime decreased significantly.

User-defined FastReader class

It is one of the most efficient and recommended methods for fast I/O in java. It uses the time advantage of BufferedReader and Stringtokenizer and uses the user-defined method for less typing, therefore, giving a fast I/O in java.

It is very easy to remember and fast enough to meet your needs for fast I/O in java for competitive programming.it uses all the inbuild methods which are fast and to avoid too much typing it wraps them in easy to type functions.

Code:

// program with user defined FastReader
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
 
public class Main {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
 
        public FastReader()
        {
            br = new BufferedReader(
                new InputStreamReader(System.in));
        }
 
        String next()
        {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
 
        int nextInt() { return Integer.parseInt(next()); }
 
        long nextLong() { return Long.parseLong(next()); }
 
        double nextDouble()
        {
            return Double.parseDouble(next());
        }
 
        String nextLine()
        {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
 
    public static void main(String[] args)
    {
        FastReader s = new FastReader();
       
    		int n = s.nextInt();
    		int[] array = new int[n];
    		for(int i=0;i<n;i++)
    		{
    		    array[i]= s.nextInt();
    		}
    		for(int i=0;i<n;i++)
    		{
    		    if(array[i]/4>0)
    		    {
    		        array[i]=array[i]/4;
    		    }
    		    else
    		    {
    		        array[i]=-1;
    		    }
    		}
    	   for(int i=0;i<n;i++)
    	   {
    	       System.out.print(array[i]+" ");
    	   }
    	   System.out.print("\n");
      }
		
}

The runtime for the above code:

The runtime in this method increased in comparison to the Bufferedreader but this method is recommended due to less typing. You can include the above given fast reader class in your snippet for fast typing.

Using Reader Class

This is one of the fastest methods for fast I/O in java but is not recommended as it is hard to implement and hard to remember. It is hard because it implements some cumbersome methods. It uses inputDataStream to read through the stream of data and uses read() method and nextInt() methods for taking inputs.

It is the fastest method in java for input. It is an abstract class, it will override some of the methods to provide higher efficiency, additional functionality, or both.

Code:

// program using Reader Class
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
 
public class Main {
    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;
 
        public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }
 
        public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(
                new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }
 
        public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') {
                    if (cnt != 0) {
                        break;
                    }
                    else {
                        continue;
                    }
                }
                buf[cnt++] = (byte)c;
            }
            return new String(buf, 0, cnt);
        }
 
        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ') {
                c = read();
            }
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
 
            if (neg)
                return -ret;
            return ret;
        }
 
        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }
 
        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
 
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
 
            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }
 
            if (neg)
                return -ret;
            return ret;
        }
 
        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0,
                                 BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }
 
        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }
 
        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }
 
    public static void main(String[] args)
        throws IOException
    {
        Reader s = new Reader();
       
    		int n = s.nextInt();
    		int[] array = new int[n];
    		for(int i=0;i<n;i++)
    		{
    		    array[i]= s.nextInt();
    		}
    		for(int i=0;i<n;i++)
    		{
    		    if(array[i]/4>0)
    		    {
    		        array[i]=array[i]/4;
    		    }
    		    else
    		    {
    		        array[i]=-1;
    		    }
    		}
    	   for(int i=0;i<n;i++)
    	   {
    	       System.out.print(array[i]+" ");
    	   }
    	  
	   
       }
}

Runtime for above code:

Despite having less and approximately half runtime compared to the Scanner method, this method is not recommended due to its tough and complicated approach.

Frequently Asked Questions

What is fast I/O?

Fast I/O refers to the methods of taking input in a programming language fastly which helps to improve the performance of a program in the given language.

What is I/O in Java?

The Java I/O (input and output) package java.io, provides a set of input streams and a set of output streams used to read and write data to files or other input and output sources.

What are the types of I/O streams?

There are two types of I/O that are created for us automatically.
1. Character stream
2. Byte stream

What is the I/O exception?

An I/O (Input-Output) Exception is a built-in exception thrown by the compiler if something is wrong with input or output in a program.

Key Takeaways

The article discussed some of the fast I/O in java and compared all the methods with the help of a problem to find the best method for fast I/O in java.

The article discussed Scanner, BufferedReder, and user-defined class for fast I/O in java for competitive programming.

If you are looking for a roadmap for competitive coding you can take a look at this article you will find helpful.

If you are preparing to crack competitions like Google Codejam, Facebook Hacker Cup, and ACM-ICPC you can look out for our competitive programming course.

By Pranchal Agrahari