Math vs 삼항연산자

Minji·2022년 10월 23일
0

문제- 파티

백준의 파티 문제를 풀면서 플로이드 워샬 알고리즘을 사용할 때 Math.max()삼항연산자의 차이에 대해 알게되었다.

삼항연산자 or if문 사용

메모리시간
36704 kb2796 ms
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Boj_1238 {
	static int INF = 1_000_000_000;
	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		//BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = null;
		st = new StringTokenizer(in.readLine(), " ");
		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		int X = Integer.parseInt(st.nextToken()); // 파티장소
		int[][] town = new int[N + 1][N + 1];
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				if (i != j)
					town[i][j] = INF;
			}
		}

		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(in.readLine(), " ");
			int start = Integer.parseInt(st.nextToken());
			int end = Integer.parseInt(st.nextToken());
			int T = Integer.parseInt(st.nextToken());
			town[start][end] = T;
		}

		for (int k = 1; k <= N; k++) {
			for (int i = 1; i <= N; i++) {
				for (int j = 1; j <= N; j++) {
					int tmp = town[i][k] + town[k][j];
                    //삼항연산자 사용
					town[i][j] = town[i][j] > tmp ? tmp : town[i][j];
					//if문 사용
                    /*
                     if(town[i][j]>tmp){
                        town[i][j] = tmp;
                    }
                    */
				}
			}
		}

		int answer = Integer.MIN_VALUE;
		for (int i = 1; i <= N; i++) {
			answer = answer < (town[i][X] + town[X][i]) ? (town[i][X] + town[X][i]) : answer;
		}
		System.out.println(answer);
	}
}

Math.min(), Math.max() 사용

메모리시간
24336 kb1328 ms
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Boj_1238 {
	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = null;
		st = new StringTokenizer(in.readLine(), " ");
		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		int X = Integer.parseInt(st.nextToken()); // 파티장소
		int[][] town = new int[N + 1][N + 1];
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				if(i!=j)
					town[i][j] = 1000000;
			}
		}

		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(in.readLine(), " ");
			int start = Integer.parseInt(st.nextToken());
			int end = Integer.parseInt(st.nextToken());
			int T = Integer.parseInt(st.nextToken());
			town[start][end] = T;
		}

		for (int k = 1; k <= N; k++) {
			for (int i = 1; i <= N; i++) {
				for (int j = 1; j <= N; j++) {

					town[i][j] = Math.min(town[i][j],town[i][k]+town[k][j]);

				}
			}
		}

		int answer = Integer.MIN_VALUE;
		for (int i = 1; i <= N; i++) {
			answer = Math.max(town[i][X]+town[X][i], answer);
		}
		out.write(answer + "");
		out.flush();
		out.close();
		in.close();
	}
}

무려 시간이 반이나 줄었다.
그러나, 플로이드 워샬 알고리즘이 아닌 다른 데에서는 대부분 삼항연산자의 속도가 더 빠르다.(참고)
왜 플로이드 워샬 알고리즘에서는 삼항연산자에 비해 Math메서드의 속도가 더 빠른걸까?

Math.max()의 코드를 살펴보자

public final class Math{
	private Math() {}
    .
    .
    .
    /**
     * Returns the greater of two {@code int} values. That is, the
     * result is the argument closer to the value of
     * {@link Integer#MAX_VALUE}. If the arguments have the same value,
     * the result is that same value.
     *
     * @param   a   an argument.
     * @param   b   another argument.
     * @return  the larger of {@code a} and {@code b}.
     */
    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }
        /**
     * Returns the smaller of two {@code int} values. That is,
     * the result the argument closer to the value of
     * {@link Integer#MIN_VALUE}.  If the arguments have the same
     * value, the result is that same value.
     *
     * @param   a   an argument.
     * @param   b   another argument.
     * @return  the smaller of {@code a} and {@code b}.
     */
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }

    .
    .
    .
}

... Math의 메서드도 내부적으로 삼항연산자로 구현되어 있다.
진짜 왜일까......? JIT컴파일러? 최적화?
https://codeforces.com/blog/entry/80834

Java8버전에서는 시간 차이가 나고 Java11버전에서는 시간 차이가 나지 않고 거의 비슷했다.

profile
매일매일 성장하기 : )

0개의 댓글