본문 바로가기

독서찰기(讀書札記)/이펙티브 자바

[아이템 67] 최적화는 신중히 하라



(맹목적인 어리석음을 포함해) 그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨팅 죄악이 더 많다
(심지어 효율을 높이지도 못하면서).
- 윌리엄 울프[Wulf]

(전체의 97% 정도인) 자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다.
- 도널드 크누스[Knuth]

최적화를 할 때는 다음 두 규칙을 따르라.
첫 번째, 하지 마라.
두 번째, (전문가 한정) 아직 하지 마라.
다시 말해, 완전히 명백하고 최적화되지 않은 해법을 찾을 때까지는 하지 마라.
- M. A. 잭슨[Jackson]

 

[Why]

구현상의 문제는 나중에 최적화해 해결할 수 있지만, 아키텍처의 결함이 성능을 제한하는 상황이라면 시스템 전체를 다시 작성하지 않고는 해결하기 불가능할 수 있다.

 

[How]

빠른 프로그램보다는 좋은 프로그램을 작성하라.

  • 성능 때문에 견고한 구조를 희생하지 말자.
  • 좋은 프로그램이지만 원하는 성능이 나오지 않는다면 그 아키텍처 자체가 최적화할 수 있는 길을 안내해줄 것이다.
  • 좋은 프로그램은 정보 은닉 원칙을 따르므로 개별 구성요소의 내부를 독립적으로 설계할 수 있다.
  • 따라서 시스템의 나머지에 영향을 주지 않고도 각 요소를 다시 설계할 수 있다(아이템15).

성능을 제한하는 설계를 피하라.

  • 완성 후 변경하기가 가장 어려운 설계 요소는 바로 컴포넌트끼리, 혹은 외부 시스템과의 소통 방식이다.
  • API, 네트워크 프로토콜, 영구 저장용 데이터 포맷 등이 대표적이다.

API를 설계할 때 성능에 주는 영향을 고려하라.

  • public 타입을 가변으로 만들면, 즉 내부 데이터를 변경할 수 있게 만들면 불필요한 방어적 복사를 수없이 유발할 수 있다(아이템50).
  • 컴포지션으로 해결할 수 있음에도 상속 방식으로 설계한 public 클래스는 상위 클래스에 영원히 종속되며 그 성능 제약까지도 물려받게 된다(아이템18).
  • 인터페이스도 있는데 굳이 구현 타입을 사용하는 것 역시 좋지 않다. 특정 구현체에 종속되게 하여, 나중에 더 빠른 구현체가 나오더라도 이용하지 못하게 된다(아이템64).

성능을 위해 API를 왜곡하는 건 매우 안 좋은 생각이다.

  • API를 왜곡하도록 만든 그 성능 문제는 해당 플랫폼이나 아랫단 소프트웨어의 다음 버전에서 사라질 수도 있지만, 왜곡된 API와 이를 지원하는 데 따르는 고통은 영원히 계속될 것이다.

각각의 최적화 시도 전후로 성능을 측정하라.

  • 시도한 최적화 기법이 성능을 눈에 띄게 높이지 못하는 경우가 많고, 심지어 더 나빠지게 할 때도 있다.
  • 프로파일링 도구(profiling tool)는 최적화 노력을 어디에 집중해야 할지 찾는 데 도움을 준다.
  • jmh도 프로파일러는 아니지만 자바 코드의 상세한 성능을 알기 쉽게 보여주는 마이크로 벤치마킹 프레임워크다.

최적화 시도 전후의 성능 측정은 성능 모델이 덜 정교한 자바에서는 중요성이 더욱 크다.

  • 자바는 다양한 기본 연산에 드는 상대적인 비용을 덜 명확하게 정의하고 있다.
  • 다시 말해, 프로그래머가 작성하는 코드와 CPU에서 수행하는 명령 사이의 '추상화 격차'가 커서 최적화로 인한 성능 변화를 일정하게 예측하기가 그만큼 더 어렵다.
  • 자바의 성능 모델은 정교하지 않을뿐더러 구현 시스템, 릴리스, 프로세서마다 차이가 있다.