67. 최적화는 신중히 하라
📜 최적화에 대한 격언들
"효율성이라는 이름 아래 행해진 컴퓨팅 죄악이 (심지어 효율을 높이지도 못하면서) 다른 어떤 핑계보다 더 많다." - 월리엄 울프
"(전체의 97% 정도인) 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다." - 도널드 크누스
"최적화를 할 때는 다음 두 규칙을 따르라.
하지 마라.
(전문가 한정) 아직 하지 마라. (명백하고 최적화되지 않은 해법을 찾을 때까지)" - M. A. 잭슨
최적화의 어두운 진실
좋은 결과보다 해로운 결과
섣부른 최적화는 더욱 위험
✨ 좋은 프로그램을 먼저 작성하라!
성능 때문에 좋은 구조를 희생하지 마라
빠른 프로그램보다 좋은 프로그램
읽기 쉽고, 유지보수하기 좋고, 재사용하기 좋은 코드가 우선
견고한 구조가 최적화의 길 안내
성능 문제 발생 시, 시스템 전체에 영향 없이 해당 부분 개선 용이
특히 정보 은닉 원칙을 잘 따른 프로그램
🤔 설계 단계에서의 성능 고려
성능 문제를 완전히 무시하라는 뜻은 아니다
아키텍처 결함은 나중에 수정하기 매우 어렵거나 불가능
완성된 설계의 기본 틀을 변경 시 복잡한 시스템 생성
설계 단계에서 성능을 반드시 염두에 둬라
API 설계 시 성능 영향을 고려
가변 public 타입: 불필요한 방어적 복사를 유발 가능성
상속 남용: 컴포지션으로 가능한데 상속을 사용하면, 상위 클래스의 성능 제약까지 상속
구현 타입 사용: 인터페이스 대신 특정 구현 타입을 사용하면, 더 빠른 구현체가 나와도 활용 어려움
API 설계 실수 사례:
java.awt.Component
의getSize()
메서드public Dimension getSize() { // ... 내부 로직 ... // 매번 새 객체 생성 (방어적 복사) return new Dimension(currentWidth, currentHeight) }
가변 객체인
Dimension
을 반환하도록 설계호출 시마다 방어적 복사본 생성 필요
성능 문제 유발
결국
getWidth()
,getHeight()
메서드 추가
기존 API는 여전히 남아있어, 잘못된 설계의 폐해 지속
잘 설계된 API는 보통 성능도 좋습니다.
⚠️성능 때문에 API를 왜곡하지 마세요!
성능 문제는 플랫폼이나 라이브러리 버전업으로 해결 가능
잘못 설계된 API는 영원히 고통
🚀 언제, 어떻게 최적화해야 하는가?
측정, 측정, 측정! 📊:
최적화의 첫 규칙은 "하지 마라", 두 번째는 "아직 하지 마라"
최적화 전후로 반드시 성능 측정
추측에 기반한 최적화는 효과가 없거나 오히려 성능을 악화시킬 수 있습니다.
"90%의 시간은 10%의 코드에서 사용된다"는 사실 기억
느릴 것이라 짐작한 부분이 실제 병목 지점이 아닐 수 있습니다.
프로파일링 도구 활용 🛠️:
최적화 노력을 어디에 집중해야 할지 찾는 데 도움
병목 지점을 정확히 체크하기
jmh (마이크로벤치마킹 프레임워크)
알고리즘을 먼저 살펴보세요 🧠:
프로파일러로 병목 지점을 찾았다면, 가장 먼저 알고리즘의 효율성을 확인
비효율적인 알고리즘을 사용하고 있다면, 다른 어떤 최적화보다 알고리즘 변경이 훨씬 효과적
반복적인 개선 🔁:
병목 지점을 최적화하고, 다시 성능을 측정하세요. 만족할 때까지 이 과정을 반복합니다.
☕ 자바 환경에서의 최적화 특징
예측의 어려움: 자바는 C/C++보다 추상화 수준이 높아(코드와 실제 CPU 명령어 간의 격차), 최적화 효과를 예측하기 더 어렵습니다. 성능에 대한 잘못된 통념도 많습니다.
환경 의존성: 자바 성능 모델은 JVM 구현, 릴리스 버전, 하드웨어에 따라 달라집니다. 따라서 다양한 환경에서 프로그램을 실행한다면, 각각의 환경에서 성능을 측정하고 타협점을 찾아야 할 수도 있습니다.
복잡성 증가: 현대 자바 소프트웨어 스택(프로세서, VM, 라이브러리, 하드웨어 등)은 매우 복잡해져 성능 예측이 더욱 어려워졌습니다. 측정의 중요성이 더욱 커졌습니다.
✨ 핵심 정리 ✨
섣부른 최적화는 금물! 좋은 설계를 우선하세요.
빠른 프로그램 < 좋은 프로그램:
일단 깨끗하고 명확하며 구조가 좋은 프로그램을 작성하는 데 집중하세요.
설계 시 성능 고려
아키텍처, API, 프로토콜, 데이터 포맷 등 설계 단계에서 성능 영향을 염두에 두세요.
잘못된 설계는 나중에 수정하기 어렵습니다.
구현 후 측정
시스템 구현 완료 후 성능을 측정하세요.
병목 지점 최적화
성능이 만족스럽지 않다면 프로파일러로 병목 지점을 찾으세요.
알고리즘 확인
가장 먼저 알고리즘 효율성을 검토하고 개선하세요.
반복 및 재측정
최적화 후에는 반드시 다시 성능을 측정하고, 만족할 때까지 반복하세요.
Last updated