일상/레벨업 독서 35

[이펙티브 자바] Item 67 최적화는 신중히 하라.

핵심 정리 빠른 프로그램을 작성하려 안달하지 말자. 좋은 프로그램을 작성하다 보면 성능은 따라오게 마련이다. 하지만 시스템을 설계할 때, 특히 API, 네트워크 프로토콜, 영구 저장용 데이터 포맷을 설계할 때는 성능을 염두에 두어야 한다. 시스템 구현을 완료했다면 이제 성능을 측정해보라. 충분히 빠르면 그것으로 끝이다. 그렇지 않다면 프로파일러를 사용해 문제의 원인이 되는 지점을 찾아 최적화를 수행하라. 가장 먼저 어떤 알고리즘을 사용했는지 살펴보자. 알고리즘을 잘못 골랐다면 다른 저수준 최적화는 아무리 해봐야 소용이 없다. 만족할 때까지 이 과정을 반복하고, 모든 변경 후에는 성능을 측정하라. 성능 때문에 견고한 구조를 희생하지 말자. 빠른 프로그램보다는 좋은 프로그램을 작성하라. 좋은 프로그램은 정보..

[이펙티브 자바] Item 66 네이티브 메서드는 신중히 사용하라.

핵심 정리 네이티브 메서드를 사용하려거든 한번 더 생각하라. 네이티브 메서드가 성능을 개선해 주는 일은 많지 않다. 저수준 자원이나 네이티브 라이브러리를 사용해야만 해서 어쩔 수 없더라도 네이티브 코드는 최소한만 사용하고 철저히 테스트하라. 네이티브 코드 안에 숨은 단 하나의 버그가 여러분 애플리케이션 전체를 훼손할 수 있다. 자바 네이티브 인터페이스(Java Native Interface, JNI)는 자바 프로그램이 네이티브 메서드를 호출하는 기술이다. 여기서 네이티브 메서드란 C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드를 말한다. 네이티브 메서드의 주요 쓰임 1. 레지스트리 같은 플랫폼 특화 기능 사용한다. 플랫폼 특화 기능을 활용하려면 네이티브 메서드를 사용해야한다. 하지만 자바가 성숙..

[이펙티브 자바] Item 61 박싱된 기본 타입보다는 기본 타입을 사용하라.

핵심 정리 기본 타입과 박싱된 기본 타입 중 하나를 선택해야 한다면 가능하면 기본 타입을 사용하라. 기본 타입은 간단하고 빠르다. 박싱된 기본 타입을 써야 한다면 주의를 기울이자. 오토박싱이 박싱된 기본 타입을 사용할 때의 번거러움을 줄여주지만, 그 위험까지 없애주지 않는다. 두 박싱된 기본 타입을 == 연산자로 비교한다면 식별성 비교가 이뤄지는데, 이는 여러분이 원한 게 아닐 가능성이 크다. 같은 연산에서 기본 타입과 박싱된 기본 타입을 혼용하면 언박싱이 이뤄지며, 언박싱 과정에서 NullPointerException을 던질 수 있다. 마지막으로, 기본 타입을 박싱하는 작업은 필요 없는 객체를 생성하는 부작용을 나을 수 있다. 자바의 데이터 타입은 크게 두가지로 나눌 수 있다. 바로 int, doubl..

[이펙티브 자바] Item 60 정확한 답이 필요하다면 float와 double은 피하라.

핵심 정리 정확한 답이 필요한 계산에는 float나 double을 피하라. 소수점 추적은 시스템에 맡기고, 코딩 시의 불편함이나 성능 저하를 신경 쓰지 않겠다면 BigDecimal을 사용하라. BigDecimal이 제공하는 여덟 가지 반올림 모드를 이용하여 반올림을 완벽히 제어 할 수 있다. 법으로 정해진 반올림을 수행해야 하는 비즈니스 계산에서 아주 편리한 기능이다. 반면, 성능이 중요하고 소수점을 직접 추적할 수 있고 숫자가 너무 크지 않다면 int나 long을 사용하라. 숫자를 아홉 자리 십진수로 표현할 수 있다면 int를 사용하고, 열여덟 자리 십진수로 표현할 수 있다면 long을 사용하라. 열여덟 자리를 넘어가면 BigDecimal을 사용해야 한다. float와 double 타입은 금융 계산시 ..

[이펙티브 자바] Item 55 옵셔널 반환은 신중히 하라.

핵심 정리 값을 반환하지 못할 가능성이 있고, 호출 할 때마다 반환 값이 없을 가능성을 염두에 둬야하는 메서드라면 옵셔널을 반환해야 할 상황일 수 도 있다. 하지만 옵셔널 반환에는 성능 저하가 뒤따르니, 성능에 민감한 메서드라면 null을 반환하거나 예외를 던지는 편이 나을 수 있다. 그리고 옵셔널을 반환값 이외의 용도로 쓰는 경우는 매우 드물다. 메서드가 특정 조건에서 값을 반환할 수 없을 때, 취할 수 있는 선택지 1. 예외를 던진다. 하지만, 예외는 진짜 예외적인 상황에서만 사용해야 하며 예외를 생성할 때 스택 추적 전체를 캡처하므로 비용이 만만치 않다. 2. null을 반환한다. null을 반환할 수 있는 메서드를 호출할 때는, 별도의 null 처리 코드를 추가해야 한다. 3. Optional를 ..

[이펙티브 자바] Item 54 null이 아닌, 빈 컬렉션이나 배열을 반환하라

핵심 정리 null이 아닌, 빈 배열이나 컬렉션을 반환하라. null을 반환하는 API는 사용하기 어렵고 오류 처리 코드도 늘어난다. 그렇다고 성능이 좋은 것도 아니다. private final List cheesesInStock = ...; public List getCheeses() { return cheesesInStock.isEmpty() ? null : new ArrayList(cheesesInStock); } // 호출 하는 곳에서 null 체크를 매번 해줘야 한다. List cheeses = shop.getCheeses(); if (cheeses != null && cheeses.contains(Cheese.STILTON)) System.out.println("좋았어, 바로 그거야."); 컬..

[이펙티브 자바] Item 49 매개변수가 유효한지 검사하라

핵심 정리 메서드나 생성자를 작성할 때면 그 매개변수들에 어떤 제약이 있을지 생각해야 한다. 그 제약들을 문서화하고 메서드 코드 시작 부분에서 명시적으로 검사해야 한다. 이런 습관을 반드시 기르도록 하자. 그 노력은 유효성 검사가 실제 오류를 처음 걸러낼 때 충분히 보상받을 것이다. 메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 예컨대 인덱스 값은 음수이면 안 되며, 객체 참조는 null이 아니어야 하는 식이다. 이런 제약은 반드시 문서화해야 하며 메서드 몸체가 시작되기 전에 검사해야 한다. 이는 "오류는 가능한 한 빨리 (발생한 곳에서) 잡아야 한다."는 일반 원칙의 한 사례이기도 하다. 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이..

[이펙티브 자바] Item 48 스트림 병렬화는 주의해서 적용하라

핵심 정리 계산도 올바로 수행하고 성능도 빨라질 거라는 확신 없이는 스트림 파이프라인 병렬화는 시도조차 하지말라. 스트림을 잘못 병렬화하면 프로그램을 오동작하게 하거나 성능을 급격히 떨어뜨린다. 병렬화하는 편이 낫다고 믿더라도, 수정 후의 코드가 여전히 정확한지 확인하고 운영 환경과 유사한 조건에서 수행해보며 성능지표를 유심히 관찰하라. 그래서 계산도 정확하고 성능도 좋아졌음이 확실해졌을 때, 오직 그럴 때만 병렬화 버전 코드를 운영 코드에 반영해라. 자바 8부터는 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원했다. 동시성 프로그래밍을 할 때는 안전성(safety)과 응답 기능(liveness) 상태를 유지하기 위해 애써야 하는데, 병렬 스트림 파이프라인 프로그..

[이펙티브 자바] Item 37 ordinal 인덱싱 대신 EnumMap을 사용하라.

핵심 정리 배열의 인덱스를 얻기 위해 ordinal을 쓰는 것은 일반적으로 좋지 않으니, 대신 EnumMap을 사용하라. 다차원 관계는 EnumMap으로 표현하라. "애플리케이션 프로그래머는 Enum.ordinal을 (웬만해서는) 사용하지 말아야 한다(아이템 35)"는 일반 원칙의 특수한 사례다. ordinal 기반 인덱싱 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드(아이템 35)로 인덱스를 얻는 코드가 있다. 식물의 생애주기를 열거 타입으로 표현한 LifeCycle 열거 타입을 예로 보자. class Plant { enum LifeCycle {ANNUAL, PERENNIAL, BIENNIAL} final String name; final LifeCycle lifeCycle; Plant(St..

[이펙티브 자바] Item 36 비트 필드 대신 EnumSet을 사용하라.

핵심 정리 열거할 수 있는 타입을 한데 모아 집합 형태로 사용한다고 해도 비트 필드를 사용할 이유는 없다. EnumSet 클래스가 비트 필드 수준의 명료함과 성능을 제공하고 열거 타입의 장점까지 선사하기 때문이다. EnumSet의 유일한 단점이라면(자바 9까지는 아직) 불변 EnumSet을 만들 수 없다는 것이다. Collections.unmodifiableSet으로 EnumSet을 감싸 사용할 수 있다. 비트 필드 비트별 OR를 사용해 여러 상수를 하나의 집합으로 모을 수 있으며, 이렇게 만들어진 집합을 비트 필드(bit field)라 한다. 비트 필드는 예전 메모리가 부족한 상황일 때, 메모리 효율을 극대화하기 위해 사용되었다. (참고 - https://ryumodrn.tistory.com/95?ca..