Java/EffectiveJava

Effective Java Item67. 최적화는 신중히 하라.

Flambee 2025. 3. 9. 21:17

그 어떤 핑계보다 효율성이라는 이름 아래 행해진 컴퓨팅 최악이 더 많다. - 윌리엄 울프
자그마한 효율성은 모두 잊자. 섣부른 최적화가 만악의 근원이다. - 도널드 크누스
최적화를 할 때는 다음 두 규칙을 따르라. 첫번째 하지 마라. 두 번째 아직 하지 마라. 다시 말해 명백하고 최적화되지 않은 해법을 찾을 때까지는 하지 마라. - M.A 잭슨

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

  • 좋은 프로그램이지만 원하는 성능이 나오지 않는다면 그 아키텍처 자체가 최적화할 수 있는 길을 안내해줄 것이다.
  • 좋은 프로그램은 정보 은닉 원칙을 따르므로 개별 구성요소의 내부를 독립적으로 설계할 수 있다. 즉, 시스템의 나머지에 영향을 주지 않고도 각 요소를 다시 설계할 수 있다.
  • 완성된 설계의 기본 틀을 변경하려다 보면 유지보수하거나 개선하기 어려운 꼬인 구조의 시스템이 만들어지기 쉽기 때문이다. 따라서 설계 단계에서 성능을 반드시 염두에 두어야 한다.

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

  • 완성 후 변경하기가 가장 어려운 설계 요소는 바로 컴포넌트끼리, 혹은 외부 시스템과의 소통 방식이다. (API, 네트워크 프로토콜, 영구 저장용 데이터 포맷 등)
  • 이런 설계 요소들은 완성후에는 변경하기 어렵거나 불가능할 수 있어, 동시에 시스템 성능을 심각하게 제한할 수 있다.

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

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

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

  • 일반적으로 최적화는 90%의 시간과 10%의 코드에 사용한다.
  • 프로파일링 도구는 최적화 노력을 어디에 집중해야 할지 찾는 데 도움을 준다.
    • 개별 메서드의 소비 시간과 호출 횟수 같은 런타임 정보를 제공하여, 집중할 곳은 물론 알고리즘을 변경해야 한다는 사실을 알려준다.
    • 시스템 규모가 커질수록 프로파일러가 더 중요해진다.
    • 자바는 JMH를 사용하면 된다.
    • 성능 모델이 덜 정교한(c와 c++를 비교하여) 자바에서는 성능 중요성이 크다.
      • 자바의 성능 모델은 정교하지 않을뿐더러 구현 시스템, 릴리스, 프로세서마다 차이가 있다.

마지막으로 만족할 때까지 이 과정을 반복하고, 모든 변경 후에는 성능을 측정하라.