SlideShare a Scribd company logo
1 of 16
Download to read offline
NAVER WEBTOON | 장수한
성능을고민하는슬기로운개발자생활
케이스 스터디 – 일상적인 코드들
• 다음과 같은 기능을 수행하는 코드가 필요합니다.
• 사용자들이 작성한 메모를 로컬 DB에서 가져온 뒤 뷰모델로 변환하고,
• 유효하지 않은 데이터를 삭제하고 식별자가 같으면 가장 최근의 메모를 표시한다.
• 변환된 메모 데이터는 생성날짜를 기준으로 내림차순 정렬되어 사용자에게 제공된다.
• 다음과 같은 기능 구현이 필요합니다.
• 로컬 DB로부터 가져온 N개의 데이터를 모델로 변환하여,
• 데이터 유효성 검사를 수행하여 유효하지 않은 모델을 제거하고, 모델 전체에 대한 중복제거를 진행한 뒤
• 시간을 기준으로 내림차순 정렬하여 반환한다.
• 로컬 DB에 저장된 데이터는 다음과 같이 구성되어 있습니다.
• [{id: Int?, content: String?, date: Date?}]
• 데이터 유효성 검사는 다음과 같이 진행합니다.
• 3개의 필드 중 하나라도 값이 없으면 유효하지 않은 데이터로 판단한다.
• 데이터 중복제거는 다음과 같이 진행합니다.
• ID는 유일해야 한다. ID가 중복되는 경우 시간 정보가 큰 값(최근값)을 사용한다.
케이스 스터디 – 일상적인 코드들
• 일단 모델을 구현해보겠습니다.
케이스 스터디 – 일상적인 코드들
• 앞의 코드를 활용하여 직독직해 수준의 구현을 해보겠습니다.
케이스 스터디 – 일상적인 코드들
• 코드를 다듬어볼께요.
N의 습격 – 비일상적인 환경들
• 변화된 코드를 보면?
• for-in 대신 map, filter를 사용하여 반복문을 깔끔하게 정리했습니다.
• 각각의 기능이 map, filter에 함수로 할당되어 코드가 대폭 줄어들었습니다.
• 결론. 겉으로 보기에 코드가 깔끔해졌고, 트렌디하며, 한마디로 뭔가 있어보입니다.
• 무엇이 문제인가?
• 앞의 코드는 개발자가 반드시 고려해야하는 부분을 처음부터 고려하지 않은 코드입니다.
• 이를 무시하고, 코드의 모양을 아름답게 개선하여 문제는 더 깊게 숨겨졌습니다.
• 개발자가 반드시 고려해야할 사항
• 구현된 로직이 동작할 환경은 어떤가
• 적절하게 자료구조가 사용되었는가
• 작성된 로직의 복잡도는 어떻게 되는가
• 해당 코드가 포함되어 배포되었고, 메모를 10000개 가지고 있는 사용자와 만났습니다.
• …그리고 앱 실행 후, 메모를 보기 위해 사용자는 30초 이상의 시간을 기다려야 합니다.
이것을 고려하지 않으면,
개발자는 재앙을 맞이하게 됩니다.
N의 습격 – 비일상적인 환경들
• 정말 비일상적인 환경일까요?
• 메모를 10000개나 가지고 있는 사용자가 있긴한가요?
• 그리고, 10000개나 가지고 있으니까 당연히 느린거 아닌가요?
• …정말 그럴까요?
• 하나씩 살펴보겠습니다.
• 컴파일 오류가 없었고, 테스트 데이터를 넣었을 때 원하는 결과도 나왔죠.
• UI와 기능을 연결해서, 데이터가 잘 표시되는지도 확인했을 겁니다.
• 하지만 이건 환경이 아닙니다. 그저, 로직이 동작하는지 확인한거죠.
• 개발자가 반드시 고려해야할 사항, 챙기셨나요?
• 구현된 로직이 동작할 환경은 어떤가
• 적절하게 자료구조가 사용되었는가
• 작성된 로직의 복잡도는 어떻게 되는가
범인은 개발자 – 최적화된 코드들
• 구현된 로직이 동작할 환경은 어떤가
• 로직 구현 후, 테스트 데이터를 100개 정도 만들었습니다.
• 속도 측정을 해보니, 0.004초(시뮬레이터 기준). 속도 문제가 없네요.
• 그런데 왜 테스트 데이터 100개죠?
• 정말 사용자들은 그 정도의 데이터만 가지고 있을까요?
• 조금 더 신경을 써서, 1000개의 메모를 가지고 있는 사용자를 고려해봅니다.
• 속도 측정을 해보니, 0.4초(시뮬레이터 기준). 속도 문제가 없네요.
• 정말 속도 문제가 없을까요?
• 데이터는 10배 증가했는데, 왜 속도는 100배나 증가했을까요?
• 그리고 무엇보다, 사용자 데이터는 추정하면 안 됩니다.
• 여건이 허락하는 선에서, 사용자의 환경이 어떤지 알고 있어야 합니다.
범인은 개발자 – 최적화된 코드들
• 적절하게 자료구조가 사용되었는가
• 자료구조로 Array와 Set이 사용되었습니다.
• Array는 원본 모델 변환에, Set은 중복제거를 위해 사용되었죠.
• 로직을 봅니다.
• 중복제거된 ID를 도출하는 것에 Set을 사용했으니, 잘 쓴 것 같습니다.
• 그런데… Set으로 도출한 데이터를 제대로 쓴 걸까요?
• Array의 데이터를 Set에 할당하면서 중복제거를 같이 했으면 어땠을까요?
범인은 개발자 – 최적화된 코드들
• 작성된 로직의 복잡도는 어떻게 되는가
• 작성한 로직의 복잡도 계산은 했나요?
• 로직을 봅니다.
• N을 할당해보겠습니다. 최악의 경우를 상정하고, 계수를 제외한 반복 횟수만 세어보겠습니다.
• 앞에서 데이터는 10배 증가했는데, 속도는 100배 증가했죠.
• 아래 로직의 복잡도는, Ο 𝑁# . 네, 그래서 100배 증가한거죠.
+N
+N +N
+N
= 	Ν+Ν+Ν(Ν) = 2Ν + N#
범인은 개발자 – 최적화된 코드들
• 범인은 누구?
• 개.발.자. 사용자와 코드는 죄가 없습니다, 여러분.
• 개선해보겠습니다.
1) Set에 Model을 할당하기 위해 Hashable 구현
2) ID가 같으면 같은 데이터로 판단해야하므로, hashValue 구현
1) Model 변환 후, 바로 Set에 Model을 할당
2) Set.update를 활용하여 날짜값을 기준으로 중복제거 구현
3) 반복은 Model 변환에서 N, Set에 할당하면서 N = 2N
4) 복잡도는? Ο 𝑁
해피엔딩 – 슬기로운 생활들
• 개선 결과
• 개선 전, 10000개 기준 32초
• 개선 후, 10000개 기준 0.08초. 400배 빨라졌습니다.
• 슬기로운 생활을 위해, 다시 한번.
• 구현된 로직이 동작할 환경은 어떤가
• 적절하게 자료구조가 사용되었는가
• 작성된 로직의 복잡도는 어떻게 되는가
• 겉모습에 넘어가지 않도록 주의합시다.
• 그렇게 안 생겼지만 map, filter. 전부 반복문입니다.
• 보기엔 좋아보여도, 그 안에 폭탄이 심어져있을 수 있습니다.
• 테스트 데이터의 기준엔 항상 근거가 있어야 합니다.
• 추정하여 잡은 테스트 데이터의 양은 오류 검증만 할 수 있습니다.
• 정확한 환경 파악이 어렵다면, 복잡도 계산이 큰 도움을 줄 수 있습니다.
해피엔딩 – 슬기로운 생활들
• 오해를 방지하기 위해서
• map. filter. 사용하지 말란 뜻이 아닙니다. 개선된 코드에서도 쓰고 있어요.
• 코드의 모습을 깔끔하게 다듬는 과정에서 조심하자는 거죠.
• 슬기로운 생활을 위한 행동양식
• 복잡도	계산을	꼭	하세요. 복잡도	Ο 𝑁# 는 재앙을 불러옵니다. 제거하세요.
• 적절한 자료구조를 사용하면 복잡도를 낮출 수 있습니다. 단, 메모리 사용량을 신경쓰세요.
• 많은 양의 데이터를 다룰 땐, Autoreleasepool을 사용해보세요. 생각보다 효과적입니다.
• 때론 계수도 부담스러울 때가 있습니다. 반복문을 합치는 것을 고려해보세요.
• 코드의 간결함, 가독성 모두 중요하지만 기본적으로 성능이 보장되어야 합니다.
• 작성된 로직은 실제 환경과 비슷한 테스트가 필요합니다. 사용자 환경 파악, 중요합니다.
부록 – Set의 재조명
• Array와 Dictionary만 주목받는 세상…
• 여러분 Set도 있어요!
• Dictionary와 비슷하지만, Hashable Key: Value가 아닌 Hashable Value로만 구성된 자료구조
• 조건만 맞으면, Dictionary에 비해 더 깔끔한 코드를 작성할 수 있습니다.
• Set은 Hashable 하기 나름입니다.
• public func hash(into hasher: inout Hasher) 내부 구현에 따라 동일 객체 판단을 결정할 수 있습니다.
• 객체의 일부 값만 hashValue 생성에 활용하는 방식으로 가능해요.
• Set.insert, Set.update, Set.remove 차이점을 알자.
• Insert는 동일한 값이 있으면, 값이 Set에 들어가지 않아요.
• 그리고 그 시점에 Set에 추가를 시도한 값이 반환되죠.
• 만약 값이 들어갔다면? nil이 반환됩니다.
• Update는 동일한 값이 있어도, 값이 Set에 들어가요.
• 대신 기존에 있던 값이 반환되죠.
• 만약 동일한 값이 없었다면? nil이 반환됩니다.
• Remove는 값을 삭제합니다.
• 값이 삭제되었다면? 삭제된 값이 반환됩니다.
• 값이 없었다면? nil이 반환됩니다.
• Subtract, Intersection… 필요한 경우, 집합연산은 정말 유용합니다.
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활

More Related Content

What's hot

홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
devCAT Studio, NEXON
 
이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017
이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017
이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017
devCAT Studio, NEXON
 
컴포넌트 관점에서 개발하기
컴포넌트 관점에서 개발하기컴포넌트 관점에서 개발하기
컴포넌트 관점에서 개발하기
우영 주
 
프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요
Chris Ohk
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
devCAT Studio, NEXON
 
Kgc2014 삼한제국기 포스트모템 김찬웅
Kgc2014 삼한제국기 포스트모템 김찬웅Kgc2014 삼한제국기 포스트모템 김찬웅
Kgc2014 삼한제국기 포스트모템 김찬웅
Chanwoong Kim
 

What's hot (20)

[RAPA/C++] 1. 수업 내용 및 진행 방법
[RAPA/C++] 1. 수업 내용 및 진행 방법[RAPA/C++] 1. 수업 내용 및 진행 방법
[RAPA/C++] 1. 수업 내용 및 진행 방법
 
디자인 시스템 디자인하기
디자인 시스템 디자인하기디자인 시스템 디자인하기
디자인 시스템 디자인하기
 
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
 
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
[150124 박민근] 모바일 게임 개발에서 루아 스크립트 활용하기
 
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
NDC2017 언리얼엔진4 디버깅 101 - 게임 기획자, 프로그래머가 버그와 만났을 때 사용할 수 있는 지침들
 
이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017
이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017
이승재, 박경재, NDC Replay 제작기: static website, static backoffice, NDC2017
 
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 [토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
 
초고속 웹사이트 개발을 위한 Codeigniter PHP Framework
초고속 웹사이트 개발을 위한 Codeigniter PHP Framework초고속 웹사이트 개발을 위한 Codeigniter PHP Framework
초고속 웹사이트 개발을 위한 Codeigniter PHP Framework
 
컴포넌트 관점에서 개발하기
컴포넌트 관점에서 개발하기컴포넌트 관점에서 개발하기
컴포넌트 관점에서 개발하기
 
프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요
 
(책 소개) 레거시 코드 활용 전략
(책 소개) 레거시 코드 활용 전략(책 소개) 레거시 코드 활용 전략
(책 소개) 레거시 코드 활용 전략
 
Vuejs를이용한서비스구축
Vuejs를이용한서비스구축Vuejs를이용한서비스구축
Vuejs를이용한서비스구축
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
 
[TECHCON 2019: MOBILE - iOS]2.들숨에 협업 날숨에 클린코드
[TECHCON 2019: MOBILE - iOS]2.들숨에 협업 날숨에 클린코드[TECHCON 2019: MOBILE - iOS]2.들숨에 협업 날숨에 클린코드
[TECHCON 2019: MOBILE - iOS]2.들숨에 협업 날숨에 클린코드
 
[리뷰] 풀스택 개발자를 위한 MEAM 스택 입문
[리뷰] 풀스택 개발자를 위한 MEAM 스택 입문[리뷰] 풀스택 개발자를 위한 MEAM 스택 입문
[리뷰] 풀스택 개발자를 위한 MEAM 스택 입문
 
[D2]pinpoint 개발기
[D2]pinpoint 개발기[D2]pinpoint 개발기
[D2]pinpoint 개발기
 
게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법게임 프로그래밍 기초 공부법
게임 프로그래밍 기초 공부법
 
Kgc2014 삼한제국기 포스트모템 김찬웅
Kgc2014 삼한제국기 포스트모템 김찬웅Kgc2014 삼한제국기 포스트모템 김찬웅
Kgc2014 삼한제국기 포스트모템 김찬웅
 
PHP로 웹개발을 해보자
PHP로 웹개발을 해보자PHP로 웹개발을 해보자
PHP로 웹개발을 해보자
 

Similar to 200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활

임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011
devCAT Studio, NEXON
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
devCAT Studio, NEXON
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
devCAT Studio, NEXON
 
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례
Jeongsang Baek
 
[2012 03 17]clean_code 14장 점진적개선
[2012 03 17]clean_code 14장 점진적개선[2012 03 17]clean_code 14장 점진적개선
[2012 03 17]clean_code 14장 점진적개선
Jong Pil Won
 
커뮤니티와 함께한 예비개발자 성장기- 조성수님
커뮤니티와 함께한 예비개발자 성장기- 조성수님커뮤니티와 함께한 예비개발자 성장기- 조성수님
커뮤니티와 함께한 예비개발자 성장기- 조성수님
NAVER D2
 
[211]대규모 시스템 시각화 현동석김광림
[211]대규모 시스템 시각화 현동석김광림[211]대규모 시스템 시각화 현동석김광림
[211]대규모 시스템 시각화 현동석김광림
NAVER D2
 
Direct x 12 초기화
Direct x 12 초기화Direct x 12 초기화
Direct x 12 초기화
QooJuice
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
devCAT Studio, NEXON
 
아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지
YoungSu Son
 

Similar to 200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활 (20)

임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
 
청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기청강대 특강 - 프로젝트 제대로 해보기
청강대 특강 - 프로젝트 제대로 해보기
 
NDC17 장창완(최종)
NDC17 장창완(최종)NDC17 장창완(최종)
NDC17 장창완(최종)
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
 
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례
(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례
 
클린 코드 part2
클린 코드 part2클린 코드 part2
클린 코드 part2
 
[2012 03 17]clean_code 14장 점진적개선
[2012 03 17]clean_code 14장 점진적개선[2012 03 17]clean_code 14장 점진적개선
[2012 03 17]clean_code 14장 점진적개선
 
FullStack 개발자 만들기 과정 소개 (Android + MEAN Stack + Redis 다루기)
FullStack 개발자 만들기 과정 소개  (Android + MEAN Stack + Redis 다루기) FullStack 개발자 만들기 과정 소개  (Android + MEAN Stack + Redis 다루기)
FullStack 개발자 만들기 과정 소개 (Android + MEAN Stack + Redis 다루기)
 
하드웨어 스타트업의 소프트웨어 이야기
하드웨어 스타트업의 소프트웨어 이야기하드웨어 스타트업의 소프트웨어 이야기
하드웨어 스타트업의 소프트웨어 이야기
 
커뮤니티와 함께한 예비개발자 성장기- 조성수님
커뮤니티와 함께한 예비개발자 성장기- 조성수님커뮤니티와 함께한 예비개발자 성장기- 조성수님
커뮤니티와 함께한 예비개발자 성장기- 조성수님
 
[211]대규모 시스템 시각화 현동석김광림
[211]대규모 시스템 시각화 현동석김광림[211]대규모 시스템 시각화 현동석김광림
[211]대규모 시스템 시각화 현동석김광림
 
멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면
 
아이폰에 포팅해보기
아이폰에 포팅해보기아이폰에 포팅해보기
아이폰에 포팅해보기
 
애자일 프랙티스
애자일 프랙티스애자일 프랙티스
애자일 프랙티스
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)
 
Direct x 12 초기화
Direct x 12 초기화Direct x 12 초기화
Direct x 12 초기화
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
 
MongoDB in use(김인범, mongodb korea)
MongoDB in use(김인범, mongodb korea)MongoDB in use(김인범, mongodb korea)
MongoDB in use(김인범, mongodb korea)
 
아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지아키텍트가 알아야 할 12/97가지
아키텍트가 알아야 할 12/97가지
 

More from NAVER Engineering

More from NAVER Engineering (20)

디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX
 
진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)
 
서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트
 
BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호
 
이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라
 
날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기
 
쏘카프레임 구축 배경과 과정
 쏘카프레임 구축 배경과 과정 쏘카프레임 구축 배경과 과정
쏘카프레임 구축 배경과 과정
 
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
 
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
 
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
 
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
 
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
 
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
 
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
 
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
 
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
 
200819 NAVER TECH CONCERT 06_놓치기 쉬운 안드로이드 UI 디테일 살펴보기
200819 NAVER TECH CONCERT 06_놓치기 쉬운 안드로이드 UI 디테일 살펴보기200819 NAVER TECH CONCERT 06_놓치기 쉬운 안드로이드 UI 디테일 살펴보기
200819 NAVER TECH CONCERT 06_놓치기 쉬운 안드로이드 UI 디테일 살펴보기
 
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
 
200819 NAVER TECH CONCERT 02_안드로이드의 '안'자도 몰랐던 나는 어떻게 안드로이드 개발자가 되었을까?
200819 NAVER TECH CONCERT 02_안드로이드의 '안'자도 몰랐던 나는 어떻게 안드로이드 개발자가 되었을까?200819 NAVER TECH CONCERT 02_안드로이드의 '안'자도 몰랐던 나는 어떻게 안드로이드 개발자가 되었을까?
200819 NAVER TECH CONCERT 02_안드로이드의 '안'자도 몰랐던 나는 어떻게 안드로이드 개발자가 되었을까?
 
Apache Nemo
Apache NemoApache Nemo
Apache Nemo
 

200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활

  • 1.
  • 2. NAVER WEBTOON | 장수한 성능을고민하는슬기로운개발자생활
  • 3. 케이스 스터디 – 일상적인 코드들 • 다음과 같은 기능을 수행하는 코드가 필요합니다. • 사용자들이 작성한 메모를 로컬 DB에서 가져온 뒤 뷰모델로 변환하고, • 유효하지 않은 데이터를 삭제하고 식별자가 같으면 가장 최근의 메모를 표시한다. • 변환된 메모 데이터는 생성날짜를 기준으로 내림차순 정렬되어 사용자에게 제공된다. • 다음과 같은 기능 구현이 필요합니다. • 로컬 DB로부터 가져온 N개의 데이터를 모델로 변환하여, • 데이터 유효성 검사를 수행하여 유효하지 않은 모델을 제거하고, 모델 전체에 대한 중복제거를 진행한 뒤 • 시간을 기준으로 내림차순 정렬하여 반환한다. • 로컬 DB에 저장된 데이터는 다음과 같이 구성되어 있습니다. • [{id: Int?, content: String?, date: Date?}] • 데이터 유효성 검사는 다음과 같이 진행합니다. • 3개의 필드 중 하나라도 값이 없으면 유효하지 않은 데이터로 판단한다. • 데이터 중복제거는 다음과 같이 진행합니다. • ID는 유일해야 한다. ID가 중복되는 경우 시간 정보가 큰 값(최근값)을 사용한다.
  • 4. 케이스 스터디 – 일상적인 코드들 • 일단 모델을 구현해보겠습니다.
  • 5. 케이스 스터디 – 일상적인 코드들 • 앞의 코드를 활용하여 직독직해 수준의 구현을 해보겠습니다.
  • 6. 케이스 스터디 – 일상적인 코드들 • 코드를 다듬어볼께요.
  • 7. N의 습격 – 비일상적인 환경들 • 변화된 코드를 보면? • for-in 대신 map, filter를 사용하여 반복문을 깔끔하게 정리했습니다. • 각각의 기능이 map, filter에 함수로 할당되어 코드가 대폭 줄어들었습니다. • 결론. 겉으로 보기에 코드가 깔끔해졌고, 트렌디하며, 한마디로 뭔가 있어보입니다. • 무엇이 문제인가? • 앞의 코드는 개발자가 반드시 고려해야하는 부분을 처음부터 고려하지 않은 코드입니다. • 이를 무시하고, 코드의 모양을 아름답게 개선하여 문제는 더 깊게 숨겨졌습니다. • 개발자가 반드시 고려해야할 사항 • 구현된 로직이 동작할 환경은 어떤가 • 적절하게 자료구조가 사용되었는가 • 작성된 로직의 복잡도는 어떻게 되는가 • 해당 코드가 포함되어 배포되었고, 메모를 10000개 가지고 있는 사용자와 만났습니다. • …그리고 앱 실행 후, 메모를 보기 위해 사용자는 30초 이상의 시간을 기다려야 합니다. 이것을 고려하지 않으면, 개발자는 재앙을 맞이하게 됩니다.
  • 8. N의 습격 – 비일상적인 환경들 • 정말 비일상적인 환경일까요? • 메모를 10000개나 가지고 있는 사용자가 있긴한가요? • 그리고, 10000개나 가지고 있으니까 당연히 느린거 아닌가요? • …정말 그럴까요? • 하나씩 살펴보겠습니다. • 컴파일 오류가 없었고, 테스트 데이터를 넣었을 때 원하는 결과도 나왔죠. • UI와 기능을 연결해서, 데이터가 잘 표시되는지도 확인했을 겁니다. • 하지만 이건 환경이 아닙니다. 그저, 로직이 동작하는지 확인한거죠. • 개발자가 반드시 고려해야할 사항, 챙기셨나요? • 구현된 로직이 동작할 환경은 어떤가 • 적절하게 자료구조가 사용되었는가 • 작성된 로직의 복잡도는 어떻게 되는가
  • 9. 범인은 개발자 – 최적화된 코드들 • 구현된 로직이 동작할 환경은 어떤가 • 로직 구현 후, 테스트 데이터를 100개 정도 만들었습니다. • 속도 측정을 해보니, 0.004초(시뮬레이터 기준). 속도 문제가 없네요. • 그런데 왜 테스트 데이터 100개죠? • 정말 사용자들은 그 정도의 데이터만 가지고 있을까요? • 조금 더 신경을 써서, 1000개의 메모를 가지고 있는 사용자를 고려해봅니다. • 속도 측정을 해보니, 0.4초(시뮬레이터 기준). 속도 문제가 없네요. • 정말 속도 문제가 없을까요? • 데이터는 10배 증가했는데, 왜 속도는 100배나 증가했을까요? • 그리고 무엇보다, 사용자 데이터는 추정하면 안 됩니다. • 여건이 허락하는 선에서, 사용자의 환경이 어떤지 알고 있어야 합니다.
  • 10. 범인은 개발자 – 최적화된 코드들 • 적절하게 자료구조가 사용되었는가 • 자료구조로 Array와 Set이 사용되었습니다. • Array는 원본 모델 변환에, Set은 중복제거를 위해 사용되었죠. • 로직을 봅니다. • 중복제거된 ID를 도출하는 것에 Set을 사용했으니, 잘 쓴 것 같습니다. • 그런데… Set으로 도출한 데이터를 제대로 쓴 걸까요? • Array의 데이터를 Set에 할당하면서 중복제거를 같이 했으면 어땠을까요?
  • 11. 범인은 개발자 – 최적화된 코드들 • 작성된 로직의 복잡도는 어떻게 되는가 • 작성한 로직의 복잡도 계산은 했나요? • 로직을 봅니다. • N을 할당해보겠습니다. 최악의 경우를 상정하고, 계수를 제외한 반복 횟수만 세어보겠습니다. • 앞에서 데이터는 10배 증가했는데, 속도는 100배 증가했죠. • 아래 로직의 복잡도는, Ο 𝑁# . 네, 그래서 100배 증가한거죠. +N +N +N +N = Ν+Ν+Ν(Ν) = 2Ν + N#
  • 12. 범인은 개발자 – 최적화된 코드들 • 범인은 누구? • 개.발.자. 사용자와 코드는 죄가 없습니다, 여러분. • 개선해보겠습니다. 1) Set에 Model을 할당하기 위해 Hashable 구현 2) ID가 같으면 같은 데이터로 판단해야하므로, hashValue 구현 1) Model 변환 후, 바로 Set에 Model을 할당 2) Set.update를 활용하여 날짜값을 기준으로 중복제거 구현 3) 반복은 Model 변환에서 N, Set에 할당하면서 N = 2N 4) 복잡도는? Ο 𝑁
  • 13. 해피엔딩 – 슬기로운 생활들 • 개선 결과 • 개선 전, 10000개 기준 32초 • 개선 후, 10000개 기준 0.08초. 400배 빨라졌습니다. • 슬기로운 생활을 위해, 다시 한번. • 구현된 로직이 동작할 환경은 어떤가 • 적절하게 자료구조가 사용되었는가 • 작성된 로직의 복잡도는 어떻게 되는가 • 겉모습에 넘어가지 않도록 주의합시다. • 그렇게 안 생겼지만 map, filter. 전부 반복문입니다. • 보기엔 좋아보여도, 그 안에 폭탄이 심어져있을 수 있습니다. • 테스트 데이터의 기준엔 항상 근거가 있어야 합니다. • 추정하여 잡은 테스트 데이터의 양은 오류 검증만 할 수 있습니다. • 정확한 환경 파악이 어렵다면, 복잡도 계산이 큰 도움을 줄 수 있습니다.
  • 14. 해피엔딩 – 슬기로운 생활들 • 오해를 방지하기 위해서 • map. filter. 사용하지 말란 뜻이 아닙니다. 개선된 코드에서도 쓰고 있어요. • 코드의 모습을 깔끔하게 다듬는 과정에서 조심하자는 거죠. • 슬기로운 생활을 위한 행동양식 • 복잡도 계산을 꼭 하세요. 복잡도 Ο 𝑁# 는 재앙을 불러옵니다. 제거하세요. • 적절한 자료구조를 사용하면 복잡도를 낮출 수 있습니다. 단, 메모리 사용량을 신경쓰세요. • 많은 양의 데이터를 다룰 땐, Autoreleasepool을 사용해보세요. 생각보다 효과적입니다. • 때론 계수도 부담스러울 때가 있습니다. 반복문을 합치는 것을 고려해보세요. • 코드의 간결함, 가독성 모두 중요하지만 기본적으로 성능이 보장되어야 합니다. • 작성된 로직은 실제 환경과 비슷한 테스트가 필요합니다. 사용자 환경 파악, 중요합니다.
  • 15. 부록 – Set의 재조명 • Array와 Dictionary만 주목받는 세상… • 여러분 Set도 있어요! • Dictionary와 비슷하지만, Hashable Key: Value가 아닌 Hashable Value로만 구성된 자료구조 • 조건만 맞으면, Dictionary에 비해 더 깔끔한 코드를 작성할 수 있습니다. • Set은 Hashable 하기 나름입니다. • public func hash(into hasher: inout Hasher) 내부 구현에 따라 동일 객체 판단을 결정할 수 있습니다. • 객체의 일부 값만 hashValue 생성에 활용하는 방식으로 가능해요. • Set.insert, Set.update, Set.remove 차이점을 알자. • Insert는 동일한 값이 있으면, 값이 Set에 들어가지 않아요. • 그리고 그 시점에 Set에 추가를 시도한 값이 반환되죠. • 만약 값이 들어갔다면? nil이 반환됩니다. • Update는 동일한 값이 있어도, 값이 Set에 들어가요. • 대신 기존에 있던 값이 반환되죠. • 만약 동일한 값이 없었다면? nil이 반환됩니다. • Remove는 값을 삭제합니다. • 값이 삭제되었다면? 삭제된 값이 반환됩니다. • 값이 없었다면? nil이 반환됩니다. • Subtract, Intersection… 필요한 경우, 집합연산은 정말 유용합니다.