티스토리 뷰

이펙티브 자바 Effective Java 2/E
국내도서
저자 : 조슈아 블로크(Joshua Bloch) / 이병준역
출판 : 인사이트 2014.09.01
상세보기


모든 프로그래머가 알아둬야 하는 최적화 관련 격언이 세 가지 있다. 너무 많이 봐서 질릴 정도라는 분도 있겠으나, 아직 본 적이 없다면 지금 읽어보자.

맹목적인 어리석음(blind stupidity)을 비롯한 다른 어떤 이유보다도, 효율성이라는 이름으로 저질러지는 죄악이 더 많다(효율성을 반드시 성취하는 것도 아니면서 말이다).
- 윌리엄 울프(William A. Wulf)

작은 효율성(small effiency)에 대해서는, 말하자면 97% 정도에 대해서는, 잊어버려라. 섣부른 최적화는 모든 악의 근원이다.
- 도널드 커누스(Donald E. Knuth)

최적화를 할 때는 아래의 두 규칙을 따르라.
규칙1: 하지마라
규칙2: (전문가들만 따를 것) 아직은 하지마라 - 완벽히 명료한, 최적화되지 않은 해답을 얻을 때까지는.
- M. A. 잭슨(M. A. Jackson)

이 격언들은 자바 언어가 나오기 20년 전에 나온 것들이다. 최적화에 관한 심오한 진리를 잘 보여준다. 최적화는 좋을 때보다 나쁠 때가 더 많으며, 섣불리 시도하면 더더욱 나쁘다는 것이다.

성능 때문에 구조적인 원칙(architectural principle)을 희생하지마라. 빠른 프로그램이 아닌, 좋은 프로그램을 만들려 노력하라. 좋은 프로그램인데 충분히 빠르지 않다면, 좋은 구조를 갖추었기 때문에 최적화의 여지도 충분할 것이다.

설계를 할 때는 성능을 제약할 가능성이 있는 결정들을 피하라. 설계 가운데 성능에 문제가 있다는 사실이 발견된 후에 고치기가 가장 까다로운 부분은 모듈간 상호작용이나 외부와의 상호작용을 명시하는 부분이다. 이런 부분은 성능 문제가 발견된 후에는 수정하기 어렵거나 수정이 불가능하다. 또한 시스템이 낼 수 있는 성능의 최대치에 큰 영향을 준다.

API를 설계할 때 내리는 결정들이 성능에 어떤 영향을 끼칠지를 생각하라. public 자료형을 변경 가능하게 만들면 쓸데없이 방어적 복사를 많이 해야할 수 있다(규칙 39). 마찬가지로 구성(composition) 기법이 적절한 클래스에 계승(inheritance) 기법을 적용하면 해당 클래스는 영원히 상위 클래스에 묶이는데, 그 결과로 하위 클래스의 성능에 인위적인 계약이 가해질 수 도 있다(규칙 16). 또한 인터페이스가 적당할 API에 구현 자료형(implementation type)을 사용해 버리면 해당 API가 특정한 구현에 종속되므로 나중에 더 빠른 구현이 나와도 개선할 수 없게 된다(규칙52).

잘 설계된 API는 일반적으로 좋은 성능을 보인다. 좋은 성능을 내기 위해 API를 급진적으로 바꾸는 것은 바람직하지 않다.

최적화를 시도할 때마다, 전후 성능을 측정하고 비교하라. 측정 결과로 성능이 개선되지 않거나 더 나쁘지는 일이 많기 때문이다.

요약

요약하자면, 빠른 프로그램을 만들고자 애쓰지 말라는 것이다. 대신 좋은 프로그램을 짜기 위해 애쓰라. 성능은 따라올 것이다. 하지만 시스템을 설계할 때, 특히 API나 통신 프로토콜, 또는 지속성 데이터 형식을 설계할 때는 성믄 문제를 따져보라.

시스템 구현을 마쳤다면 그 성능을 측정해 보라. 충분히 빠르면 끝난 것이다. 그렇지 않다면 프로파일링 도구의 도움을 받아서 문제가 되는 것을 알아낸 다음에 최적화하라. 처음으로 해야할 일은 구현에 쓰인 알고리즘을 검토하는 것이다. 저수준 최적화를 아무리 해봐야, 알고리즘을 잘못 골랐다면 성능을 만회할 수 없다. 이 프로세스를 필요한 만큼 반복하고, 최적화 단계별로 성능을 측정하라. 만족스러울 때까지.

댓글