Java-Chip4 / StudyingRecord

강의 내용 정리📝
6 stars 2 forks source link

[이펙자바 item6] 불필요한 객체 생성을 피하라 #68

Open KimChanJin97 opened 1 year ago

KimChanJin97 commented 1 year ago

item6장을 읽고 예시코드들을 작성하면서 공부해봤습니다. 궁금한 점이 있다면 질문해주세요.

p.32

matches 메서드를 호출할 때마다 내부적으로 정규표현식으로 문자열을 매칭시키기 위해 Pattern 객체 생성 이렇게 생성된 Pattern 객체는 메모리를 차지하고 가비지 컬렉션을 유발함 그리고 정규표현식으로 매칭시키는 과정은 비용이 큰 작업임 반복해서 호출될 matches 메서드보다는 Pattern 객체를 미리 생성해놓고 이를 재사용하는 것이 성능개선에 도움이 됨 즉, 정규표현식을 컴파일하고 Pattern 객체를 생성하는 과정을 단 한번만 수행하면 됨

import java.util.regex.Pattern;

public class Matches {
    // matches 메서드 여러번 호출한다면 불필요한 Pattern 객체가 내부적으로 생성됨
    static boolean isRomanNumeral_X(String s) {
        return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
    }

    // matches 메서드 여러번 호출하더라도 불필요한 Pattern 객체가 내부적으로 생성되지 않음
    private static final Pattern Roman = Pattern.compile("^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");

    static boolean isRomanNumeral_O(String s) {
        return Roman.matcher(s).matches();
    }

    private static final int ITERATIONS = 100;

    private static long measure(Runnable runnable) {
        long start = System.nanoTime();
        for (int i = 0; i < ITERATIONS; i++) {
            runnable.run();
        }
        return System.nanoTime() - start;
    }

    public static void main(String[] args) {

        String romanNumeral = "MCMLXXVLL";

        long xTime = measure(() -> {
            for(int i=0; i<ITERATIONS; i++){
                isRomanNumeral_X(romanNumeral);
            }
        });

        long oTime = measure(() -> {
            for(int i=0; i<ITERATIONS; i++){
                isRomanNumeral_O(romanNumeral);
            }
        });

        System.out.println("isRomanNumeral_X 메서드 실행시간 : " + xTime);
        System.out.println("isRomanNumeral_O 메서드 실행시간 : " + oTime);
    }
}

p.33

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class KeySet {
    public static void main(String[] args) {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("one", 1);
        map1.put("two", 2);
        map1.put("three", 3);

        for(int i=0; i<3; i++){
            Set<String> keySet1 = map1.keySet();
            System.out.println(map1.hashCode());
            System.out.println("key set : " + keySet1);
            System.out.println("size of key set : " + keySet1.size());
        }

        System.out.println(" ");

        Map<String, Integer> map2 = new HashMap<>();
        map2.put("four", 4);
        map2.put("five", 5);
        map2.put("six", 6);

        Set<String> keySet2 = map2.keySet();
        for(int i=0; i<3; i++){
            System.out.println(map2.hashCode());
            System.out.println("key set : " + keySet2);
            System.out.println("size of key set : " + keySet2.size());
        }
    }
}

p.34

// 타입을 Long 또는 long 으로 하는 것은 큰 성능 차이를 만들 수 있다.
// 불필요한 객체 생성을 한다면 큰 성능 차이를 유발할 수 있다.

public class AutoBoxing {
    private static long sum_X() {
        Long sum = 0L; // Long
        for(long i=0; i<=Integer.MAX_VALUE; i++){
            sum += i;
        }
        return sum;
    }

    private static long sum_O() {
        long sum = 0; // long
        for(long i=0; i<=Integer.MAX_VALUE; i++){
            sum += i;
        }
        return sum;
    }

    private static long measure(Runnable runnable) {
        long start = System.nanoTime();
        runnable.run();
        return System.nanoTime() - start;
    }

    public static void main(String[] args) {

        long xTime = measure(() -> sum_X());
        long oTime = measure(() -> sum_O());

        System.out.println("sum_X 메서드 실행속도 : " + xTime);
        System.out.println("sum_O 메서드 실행속도 : " + oTime);
    }
}