1

I would like to make the following code faster, without changing the reading/writing from standard console. The first line contains the number of inputs and the subsequent lines contain a set of Integers.

import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws java.lang.Exception {
        try {
            java.io.BufferedReader r = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
            int a = Integer.parseInt(r.readLine());
            for (int i = 0; i < a; i++) {
                StringTokenizer st = new StringTokenizer(r.readLine());
                while (st.hasMoreTokens()) {
                    int first = Integer.parseInt(st.nextToken());
                    int second = Integer.parseInt(st.nextToken());
                    if (first < second)
                        System.out.println("<");
                    else if (first > second)
                        System.out.println(">");
                    else
                        System.out.println("=");
                }
            }
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }

    }
}
somaniA
  • 614
  • 2
  • 7
  • 30
  • You can try to use a [`Scanner`](https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html), but I'm not sure that it will be faster. – Florent Bayle Sep 08 '15 at 06:51
  • 2
    First of all: write good code. After that, look into efficiëncy. Don't use StringTokenizer. It has been deprecated for several versions of Java, and replaced by the split method of String. to quote the StringTokenizer api: StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead. – Stultuske Sep 08 '15 at 06:51
  • Scanner is slower than StringTokenizer. i am submitting it in codechef . – somaniA Sep 08 '15 at 06:57
  • 1
    your code have a lot of syntax error. `else` inside `for` without `if`? – Rustam Sep 08 '15 at 06:59
  • It will go faster if you can compile it. – matt Sep 08 '15 at 07:00
  • sorry about that . somehow code changed . – somaniA Sep 08 '15 at 07:02
  • @somaniA: StringTokenizer is not recommended to use in either case. – Stultuske Sep 08 '15 at 07:02

3 Answers3

0

You are performing a lot of redundant autoboxing and outboxing there which could be saved if you define first and second as primitive ints instead of java.lang.Integer wrapper classes. I doubt, however, that for any reasonable size of input you'd even notice the difference.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
0

Here are a few suggestions, I am not sure these will help a lot.

1) This,

                if (first < second)
                    System.out.println("<");
                else if (first > second)
                    System.out.println(">");
                else
                    System.out.println("=");

can be changed to

                    System.out.println(first < second
                                       ? "<"
                                       : first > second
                                         ? ">"
                                         : "="
                                      );

2) Since you are using a throws clause and your try-catch does nothing you can remove it.

3) Here,

                int first = Integer.parseInt(st.nextToken());
                int second = Integer.parseInt(st.nextToken());

You are not checking for hasMoreTokens() the second time.

4) Use split() instead of StringTokenizer. More on that here and here.

Community
  • 1
  • 1
Ghazanfar
  • 1,419
  • 13
  • 21
0

You may consider to use the BufferedReader's constructor below:

public BufferedReader(Reader in, int sz)

Giving the sz parameter a reasonable high value, can avoid the buffer to be refilled too often.


As a side note, while readLine() retuns null if the end of the stream has been reached, it's better to check its return value before calling new StringTokenizer(r.readLine()) and Integer.parseInt(r.readLine()).
The edited class follows:

public class Main {

    public static void main(String[] args) {
        BufferedReader r;
        String line;
        StringTokenizer st;
        int a, first, second;

        r = new BufferedReader(new InputStreamReader(System.in), 4096);
        try {
            line = r.readLine();
            if (line != null) {
                a = Integer.parseInt(line);
                for (int i = 0; i < a; ++i) {
                    line = r.readLine();
                    if (line == null)
                        break;
                    st = new StringTokenizer(line);
                    while (st.hasMoreTokens()) {
                        first = Integer.parseInt(st.nextToken());
                        second = Integer.parseInt(st.nextToken());
                        if (first < second)
                            System.out.println("<");
                        else if (first > second)
                            System.out.println(">");
                        else
                            System.out.println("=");
                    }
                }
            }
            r.close();
        } catch (Exception e) {
            System.err.print(e.getMessage());
        }
    }
}
fantaghirocco
  • 4,761
  • 6
  • 38
  • 48