java-squid / effective-java

effective java 3e study
105 stars 38 forks source link

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

Closed ghojeong closed 3 years ago

kses1010 commented 3 years ago

프로파일러에 대한 내용이 나와서 제가 추천하는 도서는 이상민 개발자님의 자바 성능 튜닝 이야기입니다. 조금 더 최신의 내용을 알고 싶다 -> 네이버 개발 블로그에서 이상민을 검색하면 자바 튜닝, 측정도구, 최적화에 대한 내용이 있습니다. https://d2.naver.com/search?keyword=%EC%9D%B4%EC%83%81%EB%AF%BC 이 내용은 네이버를 만든 기술 에서도 나옵니다. 코드스쿼드에 있는데 오프라인은 막아놓은 상태라 슬프네요. 또 하필 절판이라서 더 슬픔.

kses1010 commented 3 years ago

제가 자바 성능 튜닝 이야기, 네이버를 만든 기술, 이펙티브 자바의 아이템 67을 보면서 공통점은

가능하면 건드리지 마라. 건드릴생각이면 무조건 측정하고 측정 데이터의 근거로 건드리자.

였습니다.

tmdgusya commented 3 years ago

프로파일러에 대한 내용이 나와서 제가 추천하는 도서는 이상민 개발자님의 자바 성능 튜닝 이야기입니다. 조금 더 최신의 내용을 알고 싶다 -> 네이버 개발 블로그에서 이상민을 검색하면 자바 튜닝, 측정도구, 최적화에 대한 내용이 있습니다. https://d2.naver.com/search?keyword=%EC%9D%B4%EC%83%81%EB%AF%BC 이 내용은 네이버를 만든 기술 에서도 나옵니다. 코드스쿼드에 있는데 오프라인은 막아놓은 상태라 슬프네요. 또 하필 절판이라서 더 슬픔.

좋은 글 감사합니다. 아쉽게도 BTrace 링크는 막힌것 같은데 다른 자바 성능 측정도구를 이용해서 해봐야겠네요.

tmdgusya commented 3 years ago

이번 본문에서 전 아이템에서 나왔던 방어적 복사에 대한 내용이 나왔는데, 방어적 복사도 객체를 생성하는 비용이 드니까, 성능 측정에 영향을 줄 수 있으니 그런 부분이 많아 지지 않도록 최대한 설계 과정에서 고려되어야 한다는 것도 깨닫게 된것 같네요.. 근데 궁금한 것은 방어적 복사 코드로 인해성능에 문제가 일어난다면, 어떤 방식으로 줄일 수 있을지 궁금합니다

102092 commented 3 years ago

이번 본문에서 전 아이템에서 나왔던 방어적 복사에 대한 내용이 나왔는데, 방어적 복사도 객체를 생성하는 비용이 드니까, 성능 측정에 영향을 줄 수 있으니 그런 부분이 많아 지지 않도록 최대한 설계 과정에서 고려되어야 한다는 것도 깨닫게 된것 같네요.. 근데 궁금한 것은 방어적 복사 코드로 인해성능에 문제가 일어난다면, 어떤 방식으로 줄일 수 있을지 궁금합니다

p378쪽에 하단에 이에 대한 설명이 나오는 듯 해요.

  1. 해당 인스턴스를 반환할 때 불변으로 만들어서 반환하거나 (이 부분이 어떻게 성능을 최적화할 수 있을지 아직 잘 모르겠네요)
  2. Dimension 객체의 기본 타입 값을 따로 반환하거나. 2번 같은 경우, 인스턴스를 반환하는 것이 아니라 기본 타입 값을 반환함으로 성능상 문제를 줄일 수 있다고 이해했습니다.
tmdgusya commented 3 years ago

https://www.notion.so/277e98c2afdc4ecfb7f123e53d800538

스터디간 간단하게 발표할 내용 정리해 보았습니다. 사실 최적화에 관한 부분은 경험이 없어서 다른 포스트를 읽거나 책의 내용을 정리하는데 중점을 뒀네요.

david215 commented 3 years ago

@tmdgusya

방어적 복사 코드로 인해성능에 문제가 일어난다면, 어떤 방식으로 줄일 수 있을지 궁금합니다

[아이템 17] 변경 가능성을 최소화하라[아이템 50] 적시에 방어적 복사본을 만들라와 같이 연결해서 생각해보면 좋을 거 같습니다. 만약에 객체가 처음부터 불변객체였다면 (예를 들어 java.time.Instant) 객체를 복사해야할 필요 자체를 원천적으로 차단할 수 있었겠지요. 한이 말한 것처럼 객체의 기본 타입 값을 따로 반환하는 것도 한 가지 방법이고요.

객체가 근본적으로 가변성을 가지고 있는 경우에는 두 가지 전략의 트레이드오프에 대해서 생각해볼 수 있을 거 같습니다.

  1. 객체를 불변객체를 만들고 변할 때마다 변화를 적용한 새로운 불변객체를 만든다.
  2. 객체의 가변객체로 만들고 내부적으로는 자유롭게 변경하되 퍼블릭 API를 통한 접근에는 방어적 복사본을 만들어주어 반환한다.

이 객체에 대한 변화가 더 자주 일어나느냐, 아니면 퍼블릭 API를 통한 접근이 더 많이 일어나느냐에 따라 시나리오에 맞게 전략을 선택할 수 있을 거 같습니다.

저는 개인적으로 예전에는 1번 전략이 너무 비효율적인 거 아닌가 라고 생각을 했었는데 가변객체를 사용하게 되는 경우에도 방어적 복사본을 만들어야 하기 때문에 (결국 두 가지 전략 모두 객체의 복사는 일어나죠) 1번 전략도 합리적으로 보여집니다. 또 2번 전략을 취했을 경우에 퍼블릭 API가 아니라 내부적으로 사용하는 경우에도 스스로, 또 사내 팀원들이 실수를 할 수도 있고 또 함수형 프로그래밍 / 분산 컴퓨팅 등의 환경에서도 불변객체가 유리하기 때문에 대부분의 경우 1번 전략을 선택하는 것이 맞다고 느껴집니다.

하지만 트레이드오프에 대해서 생각을 해봤을 때:

  1. 내부적으로만 사용하는 private 객체이고
  2. 이 객체에 대한 변경이 자주 일어나며
  3. 이 변경이 performance bottleneck이다

라는 시나리오라면 필요에 따라 방어적 복사본도 만들지 않는 극단적(?)인 선택도 합리적일 수 있겠다고 생각합니다.

kses1010 commented 3 years ago

https://www.baeldung.com/java-profilers