tag:blogger.com,1999:blog-72605968012583973362024-02-18T22:24:24.653-08:00삽질 중개인적인 메모 저장 공간입니다.charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.comBlogger276125tag:blogger.com,1999:blog-7260596801258397336.post-82354288123725239082020-09-17T20:21:00.004-07:002020-09-29T00:23:28.256-07:00Github merge 옵션 관련 <p>Github에서 Pull request를 merge 시 git에서 제공하는 여러 merge option을 팀 공유를 위해 간략히 정리함</p><p><br></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoxc_pWzV0ICR75hCFJWQUVnvJrTJ0j96HFs7F-3nPV9yPFQlGxnrW0LRVkjrtIZNiK0TBApRp7KurYicJlZhLLiWxTVjGI7oIyTj3Aaobe0h2X5DPryfnS0rO75n5y0mJxK95JNbqlVi_/s466/pullrequest-mergebutton.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="108" data-original-width="466" height="93" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoxc_pWzV0ICR75hCFJWQUVnvJrTJ0j96HFs7F-3nPV9yPFQlGxnrW0LRVkjrtIZNiK0TBApRp7KurYicJlZhLLiWxTVjGI7oIyTj3Aaobe0h2X5DPryfnS0rO75n5y0mJxK95JNbqlVi_/w400-h93/pullrequest-mergebutton.png" width="400"></a></div><br><p><br></p><p>Github에서 Pull request merge 시 아래 가이드와 같은 merge 방법이 있음.</p><p><b>- Merge pull request</b></p><p><b>- Squash and merge</b></p><p><b>- Rebase and merge </b></p><p><br></p><p>Merging a pull request</p><p> : <a href="https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request">https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request</a></p><p><br></p><p>각 방법들은 git에서 제공하는 merge 방법으로 아래 가이드를 보면 이해하기가 쉬울 듯함.</p><p>About merge methods on GitHub </p><p>: <a href="https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/about-merge-methods-on-github">https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/about-merge-methods-on-github</a></p><p>: <a href="https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges">https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges</a></p><p>브랜치 통합하기</p><p> : <a href="https://backlog.com/git-tutorial/kr/stepup/stepup1_4.html">https://backlog.com/git-tutorial/kr/stepup/stepup1_4.html</a></p><p>3.2 Git Branching - Basic Branching and Merging </p><p> : <a href="https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging">https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging</a><br> : <a href="https://git-scm.com/docs/git-merge">https://git-scm.com/docs/git-merge</a></p><p>3.6 Git Branching - Rebasing</p><p> : <a href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing">https://git-scm.com/book/en/v2/Git-Branching-Rebasing</a><br> : <a href="https://git-scm.com/docs/git-rebase">https://git-scm.com/docs/git-rebase</a></p><p><br></p><p><br></p><p>GitHub 가이드가 가장 깔끔하게 설명을 하고 있어 간략히 발췌하면</p><p><br></p><p><b>Merge pull request</b>는 </p><p> . Pull request의 모든 commit을 default branch로 추가하고 merge commit을 생성한다.<br> . git merge 시 --no-ff option을 사용하는 것이라 merge commit을 생성하게 되는 것이다.<br> : 이 옵션은 주로 특정 branch나 개발 history를 유지하려는 경우 사용됨.<br> : <a href="https://stackoverflow.com/a/14865661">https://stackoverflow.com/a/14865661</a><br> : <a href="https://koreabigname.tistory.com/m/65">https://koreabigname.tistory.com/m/65</a></p><p><br></p><p>아래 그림을 보면 feature branch에서는 default branch 기반으로 D,E를 생성하였기 때문에 A,B,C 다음 D,E를 추가하면 되지만 merge commit을 생성하여 default branch에 추가하게 된다. </p><p><br></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi02OBC2eSuSV7Zj8Z7jxmxpPZEWvUByD61th-71erHWXxFjbnc-8x-wV8ME7CBRDOl7SqyBSkO7iKxNpDpq0xg6geq4yszOPjFsumBjpLJvz7pDyY4zQiKMB2YYvc5I4ygpq3fE1KFwMtN/s782/standard-merge-commit-diagram.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="526" data-original-width="782" height="269" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi02OBC2eSuSV7Zj8Z7jxmxpPZEWvUByD61th-71erHWXxFjbnc-8x-wV8ME7CBRDOl7SqyBSkO7iKxNpDpq0xg6geq4yszOPjFsumBjpLJvz7pDyY4zQiKMB2YYvc5I4ygpq3fE1KFwMtN/w400-h269/standard-merge-commit-diagram.png" width="400"></a></div><div><br></div><br><p><b>Squash and merge</b>는</p><p> . 용어와 같이 pull request의 commit을 하나로 모아 default branch에 추가하여 merge하게 된다. <br> . Repository 설정에서 squash merging을 허용해야 한다.<br> . 수정/개발 hisotry가 중요하지 않다면 이 옵션을 사용하여 default branch를 깔끔하게 관리할 수도 있겠음.</p><p><br></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDq0QghwLLqCZQNX17HbNWq2BvzE2c41jwb4Pb1eDODzz8eYCmCj7I60PDv8wUscDBwAmFnJ8sZEOJ0BBWWS5FF8QHiwKL9JJk2Wkjs9tR2i_m2WYgi4GVeb1x1fObpI1nw7EE8vIoCwf/s781/commit-squashing-diagram.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="477" data-original-width="781" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDq0QghwLLqCZQNX17HbNWq2BvzE2c41jwb4Pb1eDODzz8eYCmCj7I60PDv8wUscDBwAmFnJ8sZEOJ0BBWWS5FF8QHiwKL9JJk2Wkjs9tR2i_m2WYgi4GVeb1x1fObpI1nw7EE8vIoCwf/w400-h244/commit-squashing-diagram.png" width="400"></a></div><div class="separator" style="clear: both; text-align: center;"><br></div><div><br></div><b>Rebase and merge</b>는<div><br><div> . Pull request의 모든 commit이 head branch에 merge commit 없이 차례로 추가된다.</div><div> . Git repository에서 rebase merging이 허용되어야 한다.</div><div> . Github의 rebase는 git rebase와 다른 점이 있는데 git rebase는 committer 정보와 commit SHA를 변경하지 않지만 Github는 변경하는 점이 다르다고 함. </div><div> . Github에서 자동으로 Rebase and merge가 되지 않는다면 command line에서 rebase를 수행하여 conflict를 해결하고 force push를 해야 함.</div><div><br></div><div><br></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF3IBqtdJv0twSwnUuYCZncgoWIIWuDd6A690bOtzk4fv14uUUBXfkD2lUgUImQpL8qteXlNZKfBT5iPhojXqLWXZV3yaTPJiXBYsVVzcIRLL_NC4wW9Up7afhV6NUWIrb4_53lDvCVEGq/s272/%25EB%258B%25A4%25EC%259A%25B4%25EB%25A1%259C%25EB%2593%259C.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="185" data-original-width="272" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF3IBqtdJv0twSwnUuYCZncgoWIIWuDd6A690bOtzk4fv14uUUBXfkD2lUgUImQpL8qteXlNZKfBT5iPhojXqLWXZV3yaTPJiXBYsVVzcIRLL_NC4wW9Up7afhV6NUWIrb4_53lDvCVEGq/w400-h272/%25EB%258B%25A4%25EC%259A%25B4%25EB%25A1%259C%25EB%2593%259C.png" width="400"></a></div><br><div><br></div><div><br></div><div>다만 rebase 수행 시 조심해야 할 점은</div><div><br></div><div> . 작업 branch가 default branch에서 분기되어 오래되었다면 merge conflict이 더 자주 발생할 수 있음. </div><div> > default branch에 대해 자주 rebase하고 commit하면 해결 될 수 있음.</div><div> > 솔직히 Github에서 branch는 필요할 때 마다 만들어 사용하는게 맞는 것 같다.</div><div><br></div><div> . Interactive rebase 작업 도중 commit history를 잃어버릴 수 있음. </div><div> > git reflog를 이용하여 복원하거나 rebase 작업을 취소할 수 있다고 함.</div><div><br></div><div>Atlassian Bitbucket git rebase</div><div><a href="https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase">https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase</a></div><div><br></div><div><br></div><div><br></div><div>마지막으로 아래 글은 Git 사용자라면 한 번쯤 봤을 정도로 고전인 article으로</div><div><p>Project 수행 시 어떻게 branch를 관리하면 좋을지에 대한 내용이니 꼭 읽어보고 알아두어야 함.</p><p><b>A successful Git branching model</b></p><p>: <a href="https://nvie.com/posts/a-successful-git-branching-model/">https://nvie.com/posts/a-successful-git-branching-model/</a></p><p><br></p><p><br></p><p><br></p><p><br></p></div></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-67093210019899474672020-08-18T17:28:00.005-07:002020-09-28T18:40:08.317-07:00Github에서 협업 개발 시 fork 기반 개발과 branch 기반 개발 사용 관련<div>아주 사소한 것이지만 공유를 위해 대충 정리해봄.</div><div>S/W 개발은 몇 명의 팀원들이 Github을 사용하여 협업을 하는데 코드 반영을 위한 방법을 두고 팀원 간 이견이 있는 경우가 있는데 정답이 있는 것이 아니고 상황에 맞춰 선택하는 게 맞아 보여 공유를 위해 정리함. </div><div>사실 개인 생각을 적은것이고 개발 방법에 정답이 있는 것이 아니라서 상황에 맞춰 방법을 사용하면 될 것 같음.</div><div><br /></div><div><br /></div><div>결론부터 말하자면</div><div>- 소규모 팀에서의 개발이라면 같은 git repository를 clone후 branch를 사용하여 협업하는 것을 추천</div><div>- 같은 팀이 아니거나 새로운 feature 개발을 위해서는 fork 된 git repository를 사용하여 협업하는 것을 추천.</div><div><br /></div><div><br /></div><div><div>관련 다른 의견</div><div> . <a href="https://github.community/t/branch-vs-fork/1206">https://github.community/t/branch-vs-fork/1206</a></div><div> . <a href="https://stackoverflow.com/a/5389910">https://stackoverflow.com/a/5389910</a></div><div> . <a href="https://stackoverflow.com/a/3611349">https://stackoverflow.com/a/3611349</a></div><div><br /></div></div><div><br /></div><div>사실 정해진 답은 아니라서 상황에 따라 적절한 방법을 사용하면 되겠지만 모든 코드 반영은 pull request를 통해 리뷰 후 반영하는 것은 당연!</div><div><br /></div><div>특정 branch에 대해서 pull request를 강제하는 방법은 다음 가이드 참고</div><div><br /></div><div>Enabling required reviews for pull requests </div><div> : <a href="https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/enabling-required-reviews-for-pull-requests">https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/enabling-required-reviews-for-pull-requests</a></div><div><br /></div><div><br /></div><div>그리고 fork는 <br /> . Github의 기능으로 git repository를 통째로(branch 포함) 복사함.</div><div> . 개발자는 forked git repository에 patch 생성 후 원 gir repository로 pull request를 함.</div><div> . Fork 방법</div><div> : <a href="https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo">https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo</a></div><div> : 위 가이드에서 fork에 대해 원 project에 영향을 미치지 않고 마음껏 수정할 수 있도록 repository 복사한다("A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project. Mac") 라고 명시함.<br /><div> . 원 respository가 삭제되어도 fork 된 repository는 삭제되지 않음.</div></div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjReOiYs3e7wjzchY4ZQqC01v0ZnWWEleZ0YcFcfau1NpKMW0LlXKtsHgdjKLqaNwcF8IDCStXbVo2jXh-zVnnPYSV1GwTUsm13tiJ_cDzejQIhGN9o7Aw1Cny1x86wxTSfAelbW03EDVhb/s469/yPKXU.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="469" data-original-width="450" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjReOiYs3e7wjzchY4ZQqC01v0ZnWWEleZ0YcFcfau1NpKMW0LlXKtsHgdjKLqaNwcF8IDCStXbVo2jXh-zVnnPYSV1GwTUsm13tiJ_cDzejQIhGN9o7Aw1Cny1x86wxTSfAelbW03EDVhb/s320/yPKXU.png" /></a></div><br /><div><br /></div><div><br /></div><div>그래서 협업 시 fork를 사용하기 적합한 경우는 다음과 같은 상황이 아닌가 생각된다.</div><div>- Opensource Contribution과 같이 팀원이 아닌 (repository에 push할 권한이 없는) 상황에서 patch를 기여하거나</div><div>- 새로운 feature 개발을 위해 원 repository 업데이트로부터 영향을 최소하 하고자 할 경우</div><div><br /></div><div><br /></div><div>그리고 아래는 fork-centric 개발과 branch-centric 개발에 대한 의견인데 다소 fork-centric 개발에 대해 부정적이지만 참고해도 좋을 듯하다.</div><div><br /></div><div>THE DEFINITIVE GUIDE TO FORKS AND BRANCHES IN GIT </div><div> : <a href="https://www.pluralsight.com/blog/software-development/the-definitive-guide-to-forks-and-branches-in-git">https://www.pluralsight.com/blog/software-development/the-definitive-guide-to-forks-and-branches-in-git</a></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div><div><br /></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-71146351259713218282020-07-07T05:06:00.002-07:002020-07-07T05:07:58.335-07:00C++ 최적화 책, 7장 문장 최적화<div><div>C++ 최적화 책을 보게 되었고 읽으며 기억해야 할 내용을 간략히 정리 함.</div><div>C++ 언어를 사용하시거나 더 자세한 내용을 보시려면 아래 책을 꼭 읽어보세요. 오랜만에 읽는 유익한 C++ 책이네요.</div><div><br /></div><div><div><b>C++ 최적화 최고 성능을 구현하는 10가지 검증된 기법</b></div><div><b>커트 건서로스 저/옥찬호 역/박수현 감수 | 한빛미디어</b></div></div><div><a href="http://www.yes24.com/Product/Goods/74971458">http://www.yes24.com/Product/Goods/74971458</a></div><div><br /></div><div>C++ 최적화 책, 4장 문자열 최적화</div><a href="http://charlie0301.blogspot.com/2020/05/c-4.html" target="_blank">http://charlie0301.blogspot.com/2020/05/c-4.html</a><div><br /></div></div><div>C++ 최적화 책, 6장 동적 할당 변수 최적화</div><div><a href="http://charlie0301.blogspot.com/2020/06/c-6.html" target="_blank">http://charlie0301.blogspot.com/2020/06/c-6.html</a> </div><div><br /></div><div><br /></div><div><b>반복문에서 코드 제거하기<br /></b><br /></div><div><br /></div><div>- 반복문에서 종료값을 캐싱하라</div><div><br /></div><div><i>char s[] = "This string is toooooooo long ";</i></div><div><i><br /></i></div><div><i>for(size_t i=0; i< strlens(s);++i)</i></div><div><i> if(s[i] == ' ')</i></div><div><i> s[i] = '*';</i></div><div><br /></div><div>위의 경우 문자열을 탐색하며 개수를 세는 strlen() 때문에 O(n) - O(n^2)의 비용이다.</div><div>이런 경우 값을 저장해 두고 사용하면 된다.</div><div><br /></div><div><div><i>for(size_t i=0, len=strlen(s); i< len;++i)</i></div><div><i> if(s[i] == ' ')</i></div><div><i> s[i] = '*';</i></div></div><div><br /></div><div>- 효율적인 반복문을 사용하라. </div><div>다른 책에서도 do while()을 사용하는 것을 추천하던데 이유가 제대로 설명되어 있지 않았는데 이 책에서는 아래와 같이 설명</div><div><br /></div><div><i>for(초기화 표현식; 조건식; 증감문) 반복해서 실행할 코드</i></div><div>는 다음과 같이 컴파일 된다고 함</div><div><i> 초기화 표현식;</i></div><div><i>L1: if (!조건식) <b>goto L2;</b></i></div><div><i> 반복해서 실행할 코드;</i></div><div><i> 증감문;</i></div><div><i><b> goto L1;</b></i></div><div><i>L2:</i></div><div><br /></div><div>for 문은 조건식 결과가 false일 경우 두번 점프해야 함.<br /></div><div>그에 반해 do while문은 다음과 같다.</div><div><br /></div><div><i>do 반복해서 실행할 코드 while (조건식);</i></div><div>은 다음과 같이 컴파일 된다.</div><div><i>L1: 반복해서 실행할 코드</i></div><div><i> if(조건식) <b>goto L1;</b></i></div><div><br /></div><div><br /></div><div>- 반복문에서 불변 코드를 제거하라.</div><div> : 반복문 진행 중에 변경되지 않는 코드는 컴파일러가 자동으로 반복문 바깥으로 옮기지만 함수가 복잡하거나 함수의 본문이 다른 컴파일 단위에 있다면 컴파일러가 자동으로 처리할 수 없으니 직접 확인 해서 반복문 바깥으로 옮겨라.</div><div><br /></div><div><br /></div><div>- 반복문에서 불필요한 함수 호출을 제거하라.</div><div> : 반복문내의 제공하는 값이 항상 동일하거나 반복문과 상관 없는 함수는 제거하거나 외부로 옮기는 것이 맞다.</div><div><br /></div><div><br /></div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"> <b>순수함수(pure function)</b><div><br /></div><div><font size="2">아래 wikipedia를 보면 간단하게 말하면 함수에서 local static 변수, non-local 변수, parameter를 변경하거나 I/O 기기의 값을 참조하지 않아 같은 입력에 대해서 같은 출력을 제공하는 함수를 말한다. </font></div><div><font size="2"><br /></font></div><div><a href="https://en.m.wikipedia.org/wiki/Pure_function" target="_blank"><font size="2">https://en.m.wikipedia.org/wiki/Pure_function</font></a></div><div><p style="background: none rgb(255, 255, 255); border: 0px; color: #202122; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin: 0.5em 0px 1em; padding: 0px; vertical-align: baseline;"><font size="2">In <a href="https://en.m.wikipedia.org/wiki/Computer_programming" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Computer programming">computer programming</a>, a <b style="background: none; border: 0px; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;">pure function</b> is a <a href="https://en.m.wikipedia.org/wiki/Subroutine" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Subroutine">function</a> that has the following properties:<sup class="reference" id="cite_ref-1" style="background: none; border: 0px; font-family: inherit; font-stretch: inherit; font-variant: inherit; line-height: 1; margin: 0px; padding: 0px; unicode-bidi: isolate; white-space: nowrap;"><a href="https://en.m.wikipedia.org/wiki/Pure_function#cite_note-1" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;">[1]</a></sup><sup class="reference" id="cite_ref-2" style="background: none; border: 0px; font-family: inherit; font-stretch: inherit; font-variant: inherit; line-height: 1; margin: 0px; padding: 0px; unicode-bidi: isolate; white-space: nowrap;"><a href="https://en.m.wikipedia.org/wiki/Pure_function#cite_note-2" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;">[2]</a></sup></font></p><ol style="background: none rgb(255, 255, 255); border: 0px; color: #202122; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin: 0px; padding: 0px 0px 0px 2.25em; vertical-align: baseline;"><li style="background: none; border: 0px; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px 0px 10px; padding: 0px; vertical-align: baseline;"><font size="2">Its <a href="https://en.m.wikipedia.org/wiki/Return_statement" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Return statement">return value</a> is the same for the same <a href="https://en.m.wikipedia.org/wiki/Argument_of_a_function" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Argument of a function">arguments</a> (no variation with local <a href="https://en.m.wikipedia.org/wiki/Static_variable" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Static variable">static variables</a>, <a href="https://en.m.wikipedia.org/wiki/Non-local_variable" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Non-local variable">non-local variables</a>, mutable <a href="https://en.m.wikipedia.org/wiki/Value_type_and_reference_type" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Value type and reference type">reference arguments</a> or input streams from <a href="https://en.m.wikipedia.org/wiki/Input/output" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Input/output">I/O devices</a>).</font></li><li style="background: none; border: 0px; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin-bottom: inherit; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding: 0px; vertical-align: baseline;"><font size="2">Its evaluation has no <a href="https://en.m.wikipedia.org/wiki/Side_effect_(computer_science)" style="background: none; border: 0px; color: #6b4ba1; font-family: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; text-decoration-line: none; vertical-align: baseline;" title="Side effect (computer science)">side effects</a> (no mutation of local static variables, non-local variables, mutable reference arguments or I/O streams).</font></li></ol></div><div><font size="2"><br /></font></div><div><font size="2"><br /></font></div><div><font size="2">아래 글을 참고하면 pure function의 경우 컴파일러가 최적화 대상으로 인식하여 최적화 하게 된다.</font></div><div><font size="2"><br /></font></div><div><a href="https://medium.com/software-design/pure-functions-in-c-fc102fd9c5e0" target="_blank"><font size="2">https://medium.com/software-design/pure-functions-in-c-fc102fd9c5e0</font></a></div><div><br /></div></td></tr></tbody></table></div><div><br /></div><div><br /></div><div><br /></div><div>- 반복문에서 숨겨진 함수 호출을 제거하세요.</div><div> : 일반적으로 함수의 이름을 쓰고 괄호로 인수를 적어 호출하는 함수 외 클래스 타입 변수를 취급할 경우 다음 함수들이 호출 될 수 있다.</div><div> . 클래스 인스턴스의 선언 (생성자를 호출)</div><div> . 클래스 인스턴스의 초기화 (생성자를 호출)</div><div> . 클래스 인스턴스의 대입 (대입 연산자를 호출)</div><div> . 클래스 인스턴스를 포함하는 산술 표현식 (연산자 멤버 함수를 호출)</div><div> . 범위를 빠져나갈 때 (범위에서 선언된 클래스 인스턴스의 소멸자를 호출)</div><div> . 함수 인수 (각 인수 표현식은 형식 인수로 복사 생성됨)</div><div> . 클래스 인스턴스의 함수 반환 (아마도 복사 생성자를 두 번 호출)</div><div> . 표준 라이브러리 컨테이너에 항목을 삽입 (항목이 이동 또는 복사 생성됨)</div><div> . 벡터에 항목을 삽입 (벡터가 재할당될 경우 모든 항목이 이동 또는 복사 생성됨)</div><div> : 클래스의 불필요한 생성자, 연산자를 제거하거나 반복문 내에서 클래스 인스턴스 생성, 삭제, 복사를 최소한으로 하는 것이 방법</div><div><br /></div><div>- 반복문을 함수 안에 넣어 호출 오버헤드를 줄이세요.</div><div> : 문자열, 배열, 다른 자료구조를 반복하며 함수를 호출한다면 반복문 뒤집기(loop inversion) 기법을 사용하여 함수 호출 횟수를 줄여 성능 향상이 가능하다.</div><div><br /></div><div><br /></div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"><div><b><br /></b></div><div><b>loop inversion</b></div><div><br /></div><div><a href="https://en.m.wikipedia.org/wiki/Loop_inversion"><font size="2">https://en.m.wikipedia.org/wiki/Loop_inversion</font></a></div><div><font size="2">이것이 저자가 말하는 기법인지 모르겠으나 설명에 의하면 </font></div><div><font size="2">while loop을 do..while loop을 가지는 if문으로 변경하는 방법으로</font></div><div><font size="2">적절히 사용되면 cpu instruction pipelining에 의해 성능을 향상할 수 있다고 함.</font></div><div><font size="2"><br /></font></div><div><font size="2">위 링크의 어셈블리를 예를 확인하면 while loop 보다 if do..while loop이 불필요한 실행이 감소된 것을 확인할 수 있다.</font></div><font size="2"><br /><a href="https://en.m.wikipedia.org/wiki/Loop_optimization">https://en.m.wikipedia.org/wiki/Loop_optimization</a> 에서도 하나의 기법으로 소개하고 있음.</font></td></tr></tbody></table></div><div><br /></div><div><br /></div><div>* 책의 저자는 여러 저수준 최적화 기법이 있지만 생각만큼 효과가 없을 수 있다고 말하며 오히려 이미 C++ 컴파일러가 훌륭히 처리하고 있다고 함.</div><div><br /></div><div><br /></div><div><b>함수에서 코드 제거하기<br /></b><br /></div><div>함수가 호출 되면 <br />컴퓨터는 현재 실행 중인 코드의 위치를 저장하고, <br />함수 본문으로 실행 흐름을 바꾼 다음, <br />함수 호출이 끝나고 이전에 실행하던 명령어의 다음 위치로 복귀하는 방법으로<br />실행 흐름에 함수 본문을 효율적으로 집어 넣음.</div><div><br /></div><div>1. 실행 코드는 함수의 인수와 지역 변수를 저장하기 위해 호출 스택에 새 프레임을 삽입</div><div>2. 각 인수 표현식을 계산한 뒤 스택 프레임에 복사</div><div>3. 현재 실행 주소를 복사해서 스택 프레임에 반환 주소로 넣음.</div><div>4. 실행 코드는 실행 주소를 (함수를 호출한 후의 다음 문장 대신) 함수 본문의 첫 번째 문장으로 갱신</div><div>5. 함수 본문에 있는 명령어들을 실행</div><div>6. 스택 프레임에 저장되어 있는 반환 주소를 명령어 주소에 복사. 그리고 함수를 호출한 후의 문장으로 제어권을 넘김</div><div>7. 호출 스택에서 스택 프레임을 삭제</div><div><br /></div><div>함수 호출의 기본 비용</div><div>- 함수 인수</div><div> : 인수 표현식을 계산하는 비용, 인수값을 메모리 스택에 복사하는 비용 필요</div><div> : 인수 몇개는 레지스터를 통해 전달 가능하지만 많으면 스택으로 전달함.</div><div><br /></div><div>- 멤버 함수 호출(vs 함수 호출)</div><div> : 멤버 함수를 호출하는 모든 코드에는 자신을 가리키는 this 포인터가 숨겨져 있다.</div><div><br /></div><div>가상함수의 비용</div><div> - 가상 멤버 함수가 있는 클래스의 각 인스턴스는 vtable이라는 테이블을 가리키는 이름 없는 포인터를 포함</div><div> : vtable은 가상 함수들의 시그니처와 연관된 본문을 가리킴</div><div> : vtable 포인터는 역참조 비용을 줄이기 위해 클래스 인스턴스의 첫번째 필드로 만듬.</div><div> : 가상 함수를 호출하는 코드는 vtable을 가리키는 포인터를 얻고자 클래스 인스턴스를 가리키는 포인터를 역참조함. 즉 호출 시 비 순차적인 메모리를 추가로 두번 불러와야 함.</div><div><br /></div><div>파생 클래스에서의 멤버 함수 호출의 비용도 상당하다.</div><div><br /></div><div>함수를 가리키는 포인터의 비용</div><div>- 함수 포인터 (함수와 정적 멤버 함수를 가리키는 포인터)</div><div> : 코드는 함수의 실행 주소를 얻기 위해 포인터를 역참조함. 컴파일러는 인라인할 수 없음.</div><div>- 멤버 함수 포인터</div><div> : 함수 시그니처와 클래스를 모두 식별해야 하며 최악의 경우에 해당하는 성능을 갖는다고 가정해도 무리는 아님</div><div><br /></div><div>- 인수가 없는 C 스타일의 void 함수는 호출 비용이 적음.</div><div> : 함수를 인라인할 수 있다면 비용이 들지 않고 메모리 접근과 실행 비용이 전부</div><div>- 가상 다중 상속 클래스를 포함하지만 가상 함수가 없는 기본 클래스에서 파생된 클래스의 가상 함수를 호출하는 것이 최악의 경우</div><div> : 코드는 클래스 인스턴스 포인터에 더할 오프셋을 결정하기 위해 클래스 인스턴스 테이블을 역참조</div><div> : 가상 다중 상속된 함수의 인스턴스 포인터를 형성하고 vtable을 얻기 위해 인스턴스를 역참조한 뒤 함수의 실행 주소를 얻기 위해 vtable을 인덱싱</div><div><br /></div><div>- 간단한 함수는 인라인으로 선언</div><div>- 함수를 처음 사용하기 전에 정의</div><div> : 정의가 호출 전에 있다면 컴파일러가 함수를 호출하는 코드를 최적화 가능</div><div>- 사용하지 않는 다형성을 제거</div><div> : 런타임 다형성을 구현하기 위해 가상 멤버 함수를 자주 사용함.</div><div><br /></div><div>- 사용하지 않는 인터페이스를 버려라</div><div>- 템플릿으로 컴파일 타임에 구현을 선택하라</div><div>- PIMPL 관용구를 사용하는 코드를 제거하라</div><div>- 멤버 함수 대신 정적 멤버 함수를 사용하라</div><div>- 가상 소멸자를 기본 클래스로 옮겨라</div><div><br /></div><div><br /></div><div><br /></div><div>표현식 최적화<br /><br /></div><div>- 표현식을 단순하게 만들어라</div><div><i>y = a*x*x*x + b*x*x +c*x + d;</i></div><div><i>=> y = (((a*x + b)*x) + c)*x + d;</i></div><div>로 바꿔 단순화 할 수 있다.</div><div><br /></div><div>- 상수를 함께 모아라.</div><div><i>seconds = 24 * 60 * 60 * days;</i></div><div><i>seconds = days * (24 * 60 * 60);<br /></i></div><div>이런 문장을 컴파일러에서는</div><div><i>seconds = 86400 * days;</i></div><div>바꿀 수 있지만 </div><div><i>seconds = 24 * days * 60 * 60;</i></div><div>인 경우 컴파일러는 곱셈을 런타임에 계산해야 한다고 함.</div><div><br /></div><div>- 비용이 적은 연산자를 사용하라.</div><div>- 부동 소수점 연산 대신 정수 연산을 사용하라.</div><div>- double이 float보다 빠를 수 있다.</div><div>- 반복 계산을 닫힌 형태라 바꿔라</div><div><br /></div><div><br /></div><div>제어 흐름 최적화 <br /><div><br /></div></div><div>- if-elseif-else 대신 switch를 사용하라.</div><div> : if-else if-else 문은 선형 제어 흐름이고 O(n)번 비교함.</div><div> : switch문은 색인 작업을 한 번 수행하고 테이블에 있는 주소로 점프함.</div><div> . 비교하는데 O(1)이지만 색인에 사용되는 상수의 간격이 크다면 컴파일러는 상수를 정렬하여 이진 검색을 수행하는 코드를 생성함. 그래도 O(log2n)이다.</div><div><br /></div><div>- swtich나 if 대신 가상 함수를 사용하라.</div><div>- 비용이 들지 않는 예외 처리를 사용하라.</div><div> : 예외 사양을 사용하지 마라.</div><div> : 예외 사양에는 개발자가 호출한 함수 라이브러리의 함수에서 어떤 예외를 던질 수 있는지 알아내기가 어렵다.</div><div> : 예외 사양은 성능에 부정적인 영향을 미친다.</div><div> : C++11에서는 더이상 예외 사양이 사용되지 않고 noexcept라는 새로운 예외 사양이 도입됨.</div><div> . 함수를 noexcept로 선언하면 함수가 예외를 던질 수 없다고 알려주는 것임.</div><div> . 컴파일러가 이동 문법을 구현하기 위해 특정 이동 생성자와 이동 대입 연산자를 noexcept로 선언해야 한다고 요구함. 이는 예외 안정성 보장 보다 이동 문법이 중요하다는 선언과 같음.</div><div><br /></div><div><br /></div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"> <br /><div><b>noexcept 및 C++에서의 예외처리 기본 지침</b></div><div><font size="2"><br /></font></div><div><font size="2">C++11부터 정의된 keyword로 함수에서 예외를 throw 할 수 있는지를 지정할 때 사용됨.</font></div><div><font size="2"><br /></font></div><div><a href="https://docs.microsoft.com/en-us/cpp/cpp/exception-specifications-throw-cpp?view=vs-2019" target="_blank"><font size="2">https://docs.microsoft.com/en-us/cpp/cpp/exception-specifications-throw-cpp?view=vs-2019</font></a></div><div><font size="2"><br /></font></div><div><font size="2">noexcept(true)의 별칭인 throw()를 제외하고는 C++17에서 모두 제거됨.</font></div><div><font size="2">각각은 아래와 같은 의미를 가짐 </font></div><div><font size="2"><br /></font></div><div><table class="table" style="background-color: white; border-collapse: collapse; border-spacing: 0px; box-sizing: inherit; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif; outline-color: inherit; table-layout: auto; width: 600px;"><thead style="box-sizing: inherit; outline-color: inherit;"><tr style="box-sizing: inherit; outline-color: inherit;"><th style="border-bottom-style: initial; border-color: initial; border-left-style: solid; border-right-style: solid; border-top-style: initial; border-width: 0px 0px 1px; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; text-align: left; vertical-align: top; white-space: nowrap;"><span data-ttu-id="3563a-117" style="box-sizing: inherit; outline-color: inherit;"><font size="2">예외 사양</font></span></th><th style="border-bottom-style: initial; border-color: initial; border-left-style: solid; border-right-style: solid; border-top-style: initial; border-width: 0px 0px 1px; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; text-align: left; vertical-align: top; white-space: nowrap;"><span data-ttu-id="3563a-118" style="box-sizing: inherit; outline-color: inherit;"><font size="2">의미</font></span></th></tr></thead><tbody readability="35.012224938875306" style="box-sizing: inherit; outline-color: inherit;"><tr readability="41.54228855721393" style="box-sizing: inherit; outline-color: inherit;"><td style="border-bottom: 0px solid; border-left: 0px solid; border-right: 0px solid; border-top-style: solid; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; vertical-align: top;"><font size="2"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept</code><br style="box-sizing: inherit; outline-color: inherit;" /><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(true)</code><br style="box-sizing: inherit; outline-color: inherit;" /><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">throw()</code></font></td><td style="border-bottom: 0px solid; border-left: 0px solid; border-right: 0px solid; border-top-style: solid; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; vertical-align: top;"><font size="2"><span data-ttu-id="3563a-119" style="box-sizing: inherit; outline-color: inherit;">이 함수는 예외를 throw하지 않습니다.</span> <span data-ttu-id="3563a-120" style="box-sizing: inherit; outline-color: inherit;"><a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/build/reference/std-specify-language-standard-version?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-decoration-line: none;">/Std: c + + 14</a> 모드 (기본값)에서는 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept</code> 및 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(true)</code>가 동일 합니다.</span> <span data-ttu-id="3563a-121" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept</code> 또는 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(true)</code>선언 된 함수에서 예외가 throw 되는 경우 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/exception-functions?view=vs-2019#terminate" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-decoration-line: none;">std:: terminate</a> 가 호출 됩니다.</span> <span data-ttu-id="3563a-122" style="box-sizing: inherit; outline-color: inherit;"><span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">/Std: c + + 14</span> 모드에서 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">throw()</code>로 선언 된 함수에서 예외가 throw 되는 경우 결과는 정의 되지 않은 동작입니다.</span> <span data-ttu-id="3563a-123" style="box-sizing: inherit; outline-color: inherit;">특정 함수가 호출 되지 않습니다.</span> <span data-ttu-id="3563a-124" style="box-sizing: inherit; outline-color: inherit;">이는 컴파일러에서 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/exception-functions?view=vs-2019#unexpected" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-decoration-line: none;">std::</a>를 호출 하는 데 필요한 c + + 14 표준과의 차이입니다.</span><br style="box-sizing: inherit; outline-color: inherit;" /><span data-ttu-id="3563a-125" style="box-sizing: inherit; outline-color: inherit;"><span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">Visual Studio 2017 버전 15.5 이상</span>: <span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">/std: c + + 17</span> 모드에서 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept</code>, <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(true)</code>및 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">throw()</code> 모두 동일 합니다.</span> <span data-ttu-id="3563a-126" style="box-sizing: inherit; outline-color: inherit;"><span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">/Std: c + + 17</span> 모드에서 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">throw()</code>는 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(true)</code>에 대 한 별칭입니다.</span> <span data-ttu-id="3563a-127" style="box-sizing: inherit; outline-color: inherit;"><span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">/Std: c + + 17</span> 모드에서 이러한 사양 중 하나를 사용 하 여 선언 된 함수에서 예외가 throw 되는 경우 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/exception-functions?view=vs-2019#terminate" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-decoration-line: none;">std:: Terminate</a> 는 c + + 17 표준에 필요한 대로 호출 됩니다.</span></font></td></tr><tr readability="12" style="box-sizing: inherit; outline-color: inherit;"><td style="border-bottom: 0px solid; border-left: 0px solid; border-right: 0px solid; border-top-style: solid; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; vertical-align: top;"><font size="2"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(false)</code><br style="box-sizing: inherit; outline-color: inherit;" /><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">throw(...)</code><br style="box-sizing: inherit; outline-color: inherit;" /><span data-ttu-id="3563a-128" style="box-sizing: inherit; outline-color: inherit;">사양 없음</span></font></td><td style="border-bottom: 0px solid; border-left: 0px solid; border-right: 0px solid; border-top-style: solid; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; vertical-align: top;"><span data-ttu-id="3563a-129" style="box-sizing: inherit; outline-color: inherit;"><font size="2">함수는 모든 형식의 예외를 throw 할 수 있습니다.</font></span></td></tr><tr readability="18" style="box-sizing: inherit; outline-color: inherit;"><td style="border-bottom: 0px solid; border-left: 0px solid; border-right: 0px solid; border-top-style: solid; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; vertical-align: top;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;"><font size="2">throw(type)</font></code></td><td style="border-bottom: 0px solid; border-left: 0px solid; border-right: 0px solid; border-top-style: solid; box-sizing: inherit; line-height: 1.5; outline-color: inherit; overflow-wrap: break-word; padding: 0.75rem 1rem; vertical-align: top;"><font size="2"><span data-ttu-id="3563a-130" style="box-sizing: inherit; outline-color: inherit;">(<span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">C + + 14 및 이전</span>) 함수는 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">type</code>형식의 예외를 throw 할 수 있습니다.</span> <span data-ttu-id="3563a-131" style="box-sizing: inherit; outline-color: inherit;">컴파일러는 구문을 허용 하지만 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">noexcept(false)</code>로 해석 합니다.</span> <span data-ttu-id="3563a-132" style="box-sizing: inherit; outline-color: inherit;"><span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">/Std: c + + 17</span> 모드에서 컴파일러는 경고 될 때 c5043를 발생 시킵니다.</span></font></td></tr></tbody></table></div><div><font size="2"><br /></font></div><div><font size="2"><br /></font></div><div><a href="https://docs.microsoft.com/en-us/cpp/cpp/errors-and-exception-handling-modern-cpp?view=vs-2019" target="_blank"><font size="2">https://docs.microsoft.com/en-us/cpp/cpp/errors-and-exception-handling-modern-cpp?view=vs-2019</font></a></div><div><font size="2"><br /></font></div><div><span style="background-color: white; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif;">기본 지침</span></div><div><p style="background-color: white; box-sizing: inherit; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-131" style="box-sizing: inherit; outline-color: inherit;">강력한 오류 처리는 모든 프로그래밍 언어에서 어렵습니다.</span> <span data-ttu-id="0a0cd-132" style="box-sizing: inherit; outline-color: inherit;">예외가 좋은 오류 처리를 지원하는 여러 기능을 제공하기는 하지만 사용자를 대신해 모든 작업을 수행할 수는 없습니다.</span> <span data-ttu-id="0a0cd-133" style="box-sizing: inherit; outline-color: inherit;">예외 메커니즘의 혜택을 누리려면 코드를 디자인할 때 예뢰를 염두에 둡니다.</span></font></p><ul readability="52.086666666666666" style="background-color: white; box-sizing: inherit; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif; list-style: none; margin: 16px 0px 16px 38px; outline-color: inherit; padding: 0px;"><li readability="24" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-134" style="box-sizing: inherit; outline-color: inherit;">절대 발생하지 않아야 하는 오류를 확인하려면 어설션을 사용합니다.</span> <span data-ttu-id="0a0cd-135" style="box-sizing: inherit; outline-color: inherit;">예외를 사용하여 발생할 수 있는 오류, 예를 들어 공용 함수의 매개 변수에 대한 입력 유효성 검증 오류를 점검하세요.</span> <span data-ttu-id="0a0cd-136" style="box-sizing: inherit; outline-color: inherit;">자세한 내용은 <span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">예외 및 어설션</span>이라는 섹션을 참조 하십시오.</span></font></p></li><li readability="12" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-137" style="box-sizing: inherit; outline-color: inherit;">오류를 처리하는 코드가 하나 이상의 개입 함수 호출로 오류를 감지하는 코드와 분리될 수 있는 경우 예외를 사용합니다.</span> <span data-ttu-id="0a0cd-138" style="box-sizing: inherit; outline-color: inherit;">오류를 처리하는 코드가 오류를 감지하는 코드에 밀접하게 연결되어 있으면 성능이 중요한 루프에서 오류 코드를 대신 사용할지 고려합니다.</span></font></p></li><li readability="30" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-139" style="box-sizing: inherit; outline-color: inherit;">예외를 throw 하거나 전파 하는 모든 함수에 대해, 강력한 보장, 기본 보장 또는 nothrow (noexcept) 보장의 세 가지 예외 보장 중 하나를 제공 합니다.</span> <span data-ttu-id="0a0cd-140" style="box-sizing: inherit; outline-color: inherit;">자세한 내용은 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/cpp/how-to-design-for-exception-safety?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-decoration-line: none;">방법: 예외 안전성을 위한 디자인</a>을 참조 하세요.</span></font></p></li><li readability="9" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-141" style="box-sizing: inherit; outline-color: inherit;">값에 따라 예외를 발생(throw)시키고 참조로 포착(catch)합니다.</span> <span data-ttu-id="0a0cd-142" style="box-sizing: inherit; outline-color: inherit;">처리할 수 없는 것은 포착(catch)하지 않도록 주의합니다.</span></font></p></li><li readability="15" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-143" style="box-sizing: inherit; outline-color: inherit;">C++11에서 더이상 사용되지 않는 예외 사양을 사용하지 마세요.</span> <span data-ttu-id="0a0cd-144" style="box-sizing: inherit; outline-color: inherit;">자세한 내용은 <span style="box-sizing: inherit; font-weight: bolder; outline-color: inherit;">예외 사양 및 noexcept</span>섹션을 참조 하세요.</span></font></p></li><li readability="6" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><font size="2"><span data-ttu-id="0a0cd-145" style="box-sizing: inherit; outline-color: inherit;">가능하다면 표준 라이브러리 예외 형식을 사용합니다.</span> <span data-ttu-id="0a0cd-146" style="box-sizing: inherit; outline-color: inherit;"><a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/exception-class?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word; text-decoration-line: none;">예외 클래스</a> 계층 구조에서 사용자 지정 예외 형식을 파생 시킵니다.</span></font></p></li><li readability="6" style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="0a0cd-147" style="box-sizing: inherit; outline-color: inherit;"><font size="2">소멸자 또는 메모리 할당 해제 함수에서 예외가 빠져나오는 것을 허용하지 마세요.</font></span></p></li></ul></div><br /></td></tr></tbody></table><br /></div><div><br /></div><div><br /></div><div><br /></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-50897391546947639872020-06-23T03:11:00.001-07:002020-06-23T03:11:44.569-07:00C# 객체에서의 unmanged/manged resource 처리 관련 (Dispose pattern)예전에 C# RAII(Resource Acquisition Is Initialization) 게시물에서 적기는 했었는데<div><div><a href="http://charlie0301.blogspot.com/2017/02/c-raii-idiom.html">http://charlie0301.blogspot.com/2017/02/c-raii-idiom.html</a></div><div><br /></div><div>C# garbage collection의 정책상 object instance가 scope을 벗어나거나 더이상 사용되지 않더라도 바로 destory되지 않으므로 <br />- 명시적인 resource 해제를 위한 IDisposable 인터페이스를 구현하고 <br />- using문을 사용하여 object가 관리(생성,사용,삭제)되도록 해야 한다.</div><div><br /></div><div><br /></div><div>아래는 IDisposable interface에 대한 내용인데 Dispose pattern을 소개하고 있다. </div><div><br /></div><div><b>IDisposable interface</b></div><div><a href="https://docs.microsoft.com/en-us/dotnet/api/system.idisposable?view=netcore-3.1">https://docs.microsoft.com/en-us/dotnet/api/system.idisposable?view=netcore-3.1</a></div><div><b><br /></b></div><div><b>Implement a Dispose method</b></div><div><a href="https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose">https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose</a></div><div><br /></div><div><br /></div><div>Dispose pattern 예제 코드이다. 영어 주석을 간략히 한글로 달았음.</div><div><br /></div><div><div><i><font size="2"></font></i></div></div><blockquote><div><div><i><font size="2"> public class MyResource: IDisposable</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"><b> // 외부에서 전달받은 unmanaged 리소스</b></font></i></div><div><i><font size="2"> private IntPtr handle;</font></i></div><div><i><font size="2"><b> // 내부에서 생성하는 managed 리소스</b></font></i></div><div><i><font size="2"> private Component component = new Component();</font></i></div><div><i><font size="2"><b> // Dispose가 호출 되었음을 알려주는 flag</b></font></i></div><div><i><font size="2"> private bool disposed = false;</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"> public MyResource(IntPtr handle)</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"> this.handle = handle;</font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"><b> // 리소스를 해제하기 위한 method</b></font></i></div><div><i><font size="2"><b> // 하위 class에서 재정의 하지 못하도록 virtual이 아님</b></font></i></div><div><i><font size="2"> public void Dispose()</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"> Dispose(true);</font></i></div><div><i><font size="2"><b> // object가 위 Dispose메서드 호출로 정리되지만 </b></font></i></div><div><i><font size="2"><b> // object가 finalization queue에 포함되어 종료자/</b></font></i><font size="2"><b><i>finalizer</i></b></font><i><font size="2"><b>가 호출되지 않도록 </b></font></i></div><div><i><font size="2"><b> // 아래 명령어를 호출한다.</b></font></i></div><div><i><font size="2"> GC.SuppressFinalize(this);</font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"><b> // 아래 함수가 호출되는 경우는 두가지인데</b></font></i></div><div><i><font size="2"><b> // 첫번째는(disposing == true) 사용자의 코드를 통해 호출되는 경우, 이 때는 managed/unmanaged 리소스를 해제해야 한다.</b></font></i></div><div><i><font size="2"><b> // 두번째는(disposing == false) finalizer가 호출한 상황으로 다른 obejct가 어떤상황인지 모르므로 unmanaged resource만 해제해야 한다.</b></font></i></div><div><i><font size="2"> protected virtual void Dispose(bool disposing)</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"> if(!this.disposed)</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"> if(disposing)</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"><b> // 첫번째 경우 managed 리소스 해제</b></font></i></div><div><i><font size="2"> component.Dispose();</font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"><b> // 첫번째, 두번째 경우 unmanaged 리소스 해제</b></font></i></div><div><i><font size="2"> CloseHandle(handle);</font></i></div><div><i><font size="2"> handle = IntPtr.Zero;</font></i></div><div><i><font size="2"><b> // dispose가 호출되었음을 기록</b></font></i></div><div><i><font size="2"> disposed = true;</font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"> // unmanaged 리소스를 해제하기 위한 interop</font></i></div><div><i><font size="2"> [System.Runtime.InteropServices.DllImport("Kernel32")]</font></i></div><div><i><font size="2"> private extern static Boolean CloseHandle(IntPtr handle);</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"><b> // finalization을 위한 종료자/finalizer(소멸자/destructor)</b></font></i></div><div><i><font size="2"><b> // Dispose()가 호출되면 아래 코드는 호출되지 않는다.</b></font></i></div><div><i><font size="2"> ~MyResource()</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"> Dispose(false);</font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"> }</font></i></div></div><div></div></blockquote><div><br /></div><div><br /></div><div>위 Dispose pattern을 따라 구현하면</div><div>- Dispose()를 명시적으로 호출하여 자원을 해제하게 하거나<br /> 사용자가 Dispose() 호출을 잊어버렸을 때 자원을 해제할 수 있게 한다.</div><div>- Dispose()를 여러번 호출해도 문제가 없음</div><div>- 종료자/finalizer 가 호출 될 때 object가 Dispose가 된 상태라도 문제가 없다.</div><div><br /></div><div>하지만 이 pattern이 자원 해제와 메모리 해제의 결합도를 가지게하여 종료자 스레드의 부담을 증가한다는 점이 있다고 한다.</div><div><br /></div><div>함께 위 패턴을 사용함에 있어 Dispose 구현을 사용하게 하려면 Using 문이나 Try/Finally 블록을 사용하면 된다. 어차피 Using이 Try/Finally 생성처럼 동작한다고 함.</div><div><br /></div><div><a href="https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/using-statement">https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/using-statement</a></div><div><p style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"></font></i></p></div><blockquote><div><p style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2">A <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Using</code> block has three parts: acquisition, usage, and disposal.</font></i></p><ul style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; list-style: none; margin: 16px 0px 16px 38px; outline-color: inherit; padding: 0px;"><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><span style="box-sizing: inherit; outline-color: inherit;">Acquisition</span> means creating a variable and initializing it to refer to the system resource. The <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Using</code> statement can acquire one or more resources, or you can acquire exactly one resource before entering the block and supply it to the <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Using</code> statement. If you supply <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">resourceexpression</code>, you must acquire the resource before passing control to the <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Using</code> statement.</font></i></p></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><span style="box-sizing: inherit; outline-color: inherit;">Usage</span> means accessing the resources and performing actions with them. The statements between <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Using</code> and <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">End Using</code> represent the usage of the resources.</font></i></p></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><span style="box-sizing: inherit; outline-color: inherit;">Disposal</span> means calling the <a data-linktype="absolute-path" href="https://docs.microsoft.com/en-us/dotnet/api/system.idisposable.dispose" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">Dispose</a> method on the object in <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">resourcename</code>. This allows the object to cleanly terminate its resources. The <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">End Using</code> statement disposes of the resources under the <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Using</code> block's control.</font></i></p></li></ul></div><div></div></blockquote><div><br /></div><div>만약 부모 클래스를 상속하는 자식 클래스가 있다면 자식 클래스에서는 다음과 같은 패턴을 구현해야 한다고 함.</div><div><p style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"></font></i></p><blockquote><p style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2">Subclasses should implement the disposable pattern as follows:</font></i></p><ul style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; list-style: none; margin: 16px 0px 16px 38px; outline-color: inherit; padding: 0px;"><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2">They must override <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Dispose(Boolean)</code> and call the base class <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Dispose(Boolean)</code> implementation.</font></i></p></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2">They can provide a finalizer if needed. The finalizer must call <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">Dispose(false)</code>.</font></i></p></li></ul></blockquote></div><div><br /></div><div>아래 예제에서는 종료자/finalizer는 구현하지 않는 자식클래스 예제임.</div><div><br /></div><div><div><i><font size="2"></font></i></div><blockquote><div><i><font size="2">class DerivedClass : BaseClass</font></i></div><div><i><font size="2">{</font></i></div><div><i><font size="2"> bool disposed = false;</font></i></div><div><i><font size="2"> SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"> protected override void Dispose(bool disposing)</font></i></div><div><i><font size="2"> {</font></i></div><div><i><font size="2"> if (disposed)</font></i></div><div><i><font size="2"> return;</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"> if (disposing) {</font></i></div><div><i><font size="2"> handle.Dispose();</font></i></div><div><b><i><font size="2"> // 다른 managed 리소스를 해제</font></i></b></div><div><i><font size="2"> }</font></i></div><div><i><font size="2"><br /></font></i></div><div><i><font size="2"><b> // unmanaged 리소스를 해제</b></font></i></div><div><br /></div><div><i><font size="2"> disposed = true;</font></i></div><div><i><font size="2"><b> // 부모 클래스의 Dispose(bool)를 호출</b></font></i></div><div><i><font size="2"><b> base.Dispose(disposing);</b></font></i></div><div><i><font size="2"> }</font></i></div><div><i><font size="2">}</font></i></div></blockquote><div><i><font size="2"></font></i></div></div><div><br /></div><div><br /></div><div>그리고 아래 책을 보면</div><div><br /></div><div><div><b>C# 6.0 완벽 가이드 깊고 넓게 알려주는 레퍼런스 북 [ 전2권 ]</b></div><div><b>조셉 앨버허리, 벤 앨버허리 공저 / 류광 역 | 인사이트(insight) </b></div></div><div><a href="http://www.yes24.com/Product/Goods/33085047?scode=032&OzSrank=1">http://www.yes24.com/Product/Goods/33085047</a></div><div><br /></div><div>종료자/finalizer에 대한 언급이 있다.</div></div><div><br /></div><div>객체에 종료자/finalizer가 있다면 인스턴스의 메모리 해제 시 종료자/finalizer가 호출된다. </div><div>. 종료자/finalizer가 없다면 객체는 garbage collection 시 바로 삭제되지만 <br /> 종료자/finalizer가 있다면 별도의 대기열에 저장하여 관리하며 종료자/finalizer 호출 전까지 객체가 유지된다. </div><div>. 종료자 때문에 메모리할당과 garbage collection이 느려진다. (종료자 객체들의 관리 및 처리)</div><div>. 종료자는 객체와 객체가 참조하는 객체의 수명을 필요 이상으로 늘린다.</div><div>. 종료자의 호출 순서를 예측할 수 없고 시점을 제어할 수 없다.</div><div>. 종료자안에서 코드 실행이 차단되면 다른 객체의 종료자가 호출되지 못한다.</div><div>. app이 제대로 종료되지 않는다면 종료자들이 호출되지 않을 수 있다.</div><div><br /></div><div>그래서 더더욱 resource 해제를 위해서라면 위 Dispose pattern을 구현하는것이 맞겠다.</div><div><br /></div><div><br /></div><div>마지막으로 Garbage collection에 대해 설명하는 공식 문서</div><div><a href="https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals">https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals</a></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-62211808847355595182020-06-10T05:33:00.000-07:002020-06-10T05:33:12.447-07:00C++ 최적화 책, 6장 동적 할당 변수 최적화<div>C++ 최적화 책을 보게 되었고 읽으며 기억해야 할 내용을 간략히 정리 함.</div><div>C++ 언어를 사용하시거나 더 자세한 내용을 보시려면 아래 책을 꼭 읽어보세요. 오랜만에 읽는 유익한 C++ 책이네요.</div><div><br /></div><div><div><b>C++ 최적화 최고 성능을 구현하는 10가지 검증된 기법</b></div><div><b>커트 건서로스 저/옥찬호 역/박수현 감수 | 한빛미디어</b></div></div><div><a href="http://www.yes24.com/Product/Goods/74971458">http://www.yes24.com/Product/Goods/74971458</a></div><div><br /></div><div>C++ 최적화 책, 4장 문자열 최적화</div><a href="http://charlie0301.blogspot.com/2020/05/c-4.html" target="_blank">http://charlie0301.blogspot.com/2020/05/c-4.html</a><div><br /></div><div><br /></div><div><b>C++ 변수</b></div><div><div><br /></div><div>- C++ 변수는 고정된 레이아웃을 가지고 컴파일 타임에 크기가 결정됨</div><div>- 변수는 저장 기간(수명)을 가짐</div><div>- <b>정적 저장 기간</b></div><div> . 컴파일러가 예약해둔 메모리에 상주</div><div> . 메모리 주소는 컴파일 타임에 결정</div><div> . 전역 정적 변수는 main()함수 진입 전에 생성, main()함수를 떠난뒤 파괴</div><div> . 함수에서 선언한 정적 변수는 함수에 처음 진입하기 전에 생성</div><div> </div><div>- <b>스레드 지역 저장 기간</b></div><div> . C++ 11 이후 thread-local storage(TLS) 변수를 선언 가능</div><div> . 스레드 진입 시 생성, 스레드가 끝나면 파괴</div><div> . thread_local 키워드로 선언된 변수는 스레드 지역 저장 기간을 가짐</div><div><br /></div><div>- <b>자동 저장 기간</b></div><div> . 함수 호출 스텍에서 컴파일러가 예약해둔 메모리 상주</div><div> . 컴파일 타임에 메모리 크기 결정</div><div> . 함수 호출 스택 포인터에서 고정된 오프셋 위치를 가짐</div><div> . 코드 블록 {} 안에 존재하므로 {} 진입 시 생성, 빠져나오면 파괴</div><div><br /></div><div>- <b>동적 저장 기간</b></div><div> . 실행 중인 프로그램에서 요청한 메모리에 상주</div><div> . 프로그램에서 new로 명시적으로 저장 공간을 요청하고 delete로 파괴</div><div> . 메모리 관리자가 메모리 관리</div><div> . 자동 변수와 마찬가지로 주소는 런타임에 결정</div><div><br /></div><div><br /></div><div>- 변수의 소유권( 변수의 생성, 파괴를 결정하는 주체를 설명하기 위한 개념인듯)</div><div> : <b>전역 소유권</b></div><div> . 프로그램이 가지며 main()함수 진입 전 생성되고 main()함수를 떠난 뒤 파괴 됨.</div><div> : <b>유효 범위가 지정된 소유권</b> </div><div> . 중괄호로 둘러 싸인 코드블록의 유효 범위가 소유권을 가짐. </div><div> . main() 함수의 {} 도 해당 되며 main()함수에서 선언된 자동 변수는 정적 변수와 동일한 수명을 가짐</div><div> : <b>멤버 소유권</b> </div><div> . 클래스 인스턴스가 가짐. </div><div> . 클래스 인스턴스가 생성될 때 생성되며 인스턴스가 파괴될 때 파괴됨.</div><div> : <b>동적변수의 소유권</b> </div><div> . 정해져 있지 않고 프로그램에서 명시적으로 관리해야 함. </div><div> . new로 만들어진 포인터를 프로그램이 관리하고 더이상 사용하지 않는 경우 delete로 제거해야 함. (포인터 날로 쓰는게 가장 싫었음. 가능하면 동적 변수는 스마트 포인터로 관리하는게 맞는 방법임.)</div><div><br /></div><div><br /></div><div>- C++11의 nullptr이라는 특정한 값은 유효한 메모리를 가지키지 않는다. </div><div> : 0을 nullptr로 변환할 수 있지만 0 != nullptr 이다.</div><div><br /></div><div><br /></div><div><div><a href="https://docs.microsoft.com/ko-kr/cpp/cpp/smart-pointers-modern-cpp?view=vs-2019#c-standard-library-smart-pointers" target="_blank">https://docs.microsoft.com/ko-kr/cpp/cpp/smart-pointers-modern-cpp?view=vs-2019#c-standard-library-smart-pointers</a></div></div><div><i><font size="2"><br /></font></i></div><div><p style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="3ca81-142" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">POCO(Plain Old C++ 개체)에 대한 포인터를 캡슐화하는 데 가장 먼저 스마트 포인터를 사용합니다.</font></i></span></p><ul readability="25.641337386018236" style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; list-style: none; margin: 16px 0px 16px 38px; outline-color: inherit; padding: 0px;"><li readability="21" style="box-sizing: inherit; list-style: disc outside none; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">unique_ptr</code><br style="box-sizing: inherit; outline-color: inherit;" /><span data-ttu-id="3ca81-143" style="box-sizing: inherit; outline-color: inherit;">기본 포인터로 한 명의 소유자만 허용합니다.</span> <span data-ttu-id="3ca81-144" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">shared_ptr</code>이 필요하다는 점을 확실히 알 경우 POCO의 기본 선택으로 사용합니다.</span> <span data-ttu-id="3ca81-145" style="box-sizing: inherit; outline-color: inherit;">새 소유자로 이동할 수 있지만 복사하거나 공유할 수 없습니다.</span> <span data-ttu-id="3ca81-146" style="box-sizing: inherit; outline-color: inherit;">사용하지 않는 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">auto_ptr</code>을 대체합니다.</span><span data-ttu-id="3ca81-147" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">boost::scoped_ptr</code>과 비교합니다.</span> <span data-ttu-id="3ca81-148" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">unique_ptr</code>작고 효율적입니다. 크기는 하나의 포인터이며 C++ 표준 라이브러리 컬렉션에서 빠른 삽입 및 검색을 위한 rvalue 참조를 지원합니다.</span> <span data-ttu-id="3ca81-149" style="box-sizing: inherit; outline-color: inherit;">헤더 파일: <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;"><memory></code>.</span> <span data-ttu-id="3ca81-150" style="box-sizing: inherit; outline-color: inherit;">자세한 내용은 unique_ptr 인스턴스 및 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/unique-ptr-class?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">unique_ptr 클래스를</a> <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/cpp/how-to-create-and-use-unique-ptr-instances?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">만드는 방법( 사용 방법)을</a> 참조하십시오.</span></font></i></p></li><li readability="24" style="box-sizing: inherit; list-style: disc outside none; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">shared_ptr</code><br style="box-sizing: inherit; outline-color: inherit;" /><span data-ttu-id="3ca81-151" style="box-sizing: inherit; outline-color: inherit;">참조 횟수가 계산되는 스마트 포인터입니다.</span> <span data-ttu-id="3ca81-152" style="box-sizing: inherit; outline-color: inherit;">원시 포인터 하나를 여러 소유자에게 할당하려고 할 경우 사용합니다(예: 컨테이너에서 포인터 복사본을 반환할 때 원본을 유지하고 싶을 경우).</span> <span data-ttu-id="3ca81-153" style="box-sizing: inherit; outline-color: inherit;">원시 포인터는 모든 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">shared_ptr</code> 소유자가 범위를 벗어나거나 소유권을 포기할 때까지 삭제되지 않습니다.</span> <span data-ttu-id="3ca81-154" style="box-sizing: inherit; outline-color: inherit;">크기는 2개의 포인터입니다. 하나는 개체용이고, 다른 하나는 참조 횟수가 포함된 공유 제어 블록용입니다.</span><span data-ttu-id="3ca81-155" style="box-sizing: inherit; outline-color: inherit;">헤더 파일: <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;"><memory></code>.</span> <span data-ttu-id="3ca81-156" style="box-sizing: inherit; outline-color: inherit;">자세한 내용은 인스턴스 및 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/shared-ptr-class?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">shared_ptr 클래스를</a><a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">shared_ptr 만드는 방법: 인스턴스 만들기 및 사용</a> 방법을 참조하십시오.</span></font></i></p></li><li readability="24" style="box-sizing: inherit; list-style: disc outside none; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">weak_ptr</code><br style="box-sizing: inherit; outline-color: inherit;" /><span data-ttu-id="3ca81-157" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">shared_ptr</code>과 함께 사용할 수 있는 특별한 경우의 스마트 포인터입니다.</span><span data-ttu-id="3ca81-158" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">weak_ptr</code>은 하나 이상의 <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">shared_ptr</code> 인스턴스가 소유하는 개체에 대한 액세스를 제공하지만, 참조 수 계산에 참가하지 않습니다.</span> <span data-ttu-id="3ca81-159" style="box-sizing: inherit; outline-color: inherit;">개체를 관찰하는 동시에 해당 개체를 활성 상태로 유지하지 않으려는 경우 사용합니다.</span> <span data-ttu-id="3ca81-160" style="box-sizing: inherit; outline-color: inherit;"><code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">shared_ptr</code> 인스턴스 사이의 순환 참조를 차단하기 위해 필요한 경우도 있습니다.</span> <span data-ttu-id="3ca81-161" style="box-sizing: inherit; outline-color: inherit;">헤더 파일: <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;"><memory></code>.</span> <span data-ttu-id="3ca81-162" style="box-sizing: inherit; outline-color: inherit;">자세한 내용은 weak_ptr 인스턴스 및 <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/standard-library/weak-ptr-class?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">weak_ptr 클래스를</a> <a data-linktype="relative-path" href="https://docs.microsoft.com/ko-kr/cpp/cpp/how-to-create-and-use-weak-ptr-instances?view=vs-2019" style="background-color: transparent; box-sizing: inherit; cursor: pointer; outline-color: inherit; outline-style: initial; outline-width: 0px; overflow-wrap: break-word;">만드는 방법: 인스턴스 만들기 및 사용</a> 방법을 참조하십시오.</span></font></i></p></li></ul></div><div><br /></div><div><br /></div><div>스마트 포인터의 삭제 조건</div><div>- break, continue를 만났을 때, 함수에서 값을 리턴할 때, 예외가 발생하는 등 선언문을 둘러싸고 이쓴 범위를 빠져 나갈 때 소유한 동적 변수 삭제</div><div>- 클래스 멤버로 선언된 스마트 포인터는 클래스 인스턴스가 파괴될 때 소유한 동적 변수를 삭제함.</div><div>- 스레드 지역 저장 기간으로 선언된 스마트 포인터 인스턴스는 스레드가 정상 종료될 때 소유한 동적 변수를 삭제</div><div> : 운영체제가 스레드를 종료시킨 경우 일반적으로 삭제되지 않는 다고 함.</div><div>- 정적 저장 기간으로 선언된 스마트 포인터의 인스턴스는 프로그램이 종료될 때 소유한 동적 변수 삭제</div><div><br /></div><div>- 동적 변수를 한 소유자가 관리하는 경우 </div><div> : std::unique_ptr<t> 사용 추천. 비용 패널티도 거의 없음.</t></div><div><t><br /></t></div><div><t><a href="https://docs.microsoft.com/ko-kr/cpp/cpp/smart-pointers-modern-cpp?view=vs-2019" target="_blank">https://docs.microsoft.com/ko-kr/cpp/cpp/smart-pointers-modern-cpp?view=vs-2019</a></t></div><div><i><font size="2"><blockquote><span data-ttu-id="3ca81-129" style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; outline-color: inherit;">스마트 포인터는 메모리 및 성능 관점에서 최대한 효율적으로 사용할 수 있도록 설계되었습니다.</span><span style="background-color: white; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif;"> </span><span data-ttu-id="3ca81-130" style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; outline-color: inherit;">예를 들어, <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">unique_ptr</code>의 유일한 데이터 멤버는 캡슐화된 포인터입니다.</span><span style="background-color: white; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif;"> </span><span data-ttu-id="3ca81-131" style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; outline-color: inherit;">즉, <code style="background-color: var(--body-background-dark); border-radius: 3px; box-sizing: inherit; direction: ltr; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; outline-color: inherit; overflow-wrap: break-word; padding: 0.1em 0.2em;">unique_ptr</code>은 해당 포인터와 정확히 동일한 크기(4바이트 또는 8바이트)입니다.</span><span style="background-color: white; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif;"> </span><span data-ttu-id="3ca81-132" style="background-color: white; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; outline-color: inherit;">오버로드된 스마트 포인터 * 및 -> 연산자(s)를 사용하여 캡슐화된 포인터에 액세스하는 것은 원시 포인터에 직접 액세스하는 것보다 훨씬 느리지 않습니다.</span></blockquote><span data-ttu-id="3ca81-132" style="background-color: white; box-sizing: inherit; box-sizing: inherit; color: #171717; font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif; outline-color: inherit; outline-color: inherit;"></span></font></i></div><div><t><br /></t></div><div><br /></div><div>- 동적 변수를 여려명이 공유하는 경우, 두개 이상의 포인터가 동적변수를 관리하는 경우 접근 시 유효성을 확인하기 어렵고 삭제 같은 관리가 어려움. </div><div> : std::shared_ptr<t>를 사용하는 것을 추천</t></div><div> : 단 shared_ptr에 대입할 때 new 표현식에서 리턴되는 것을 바로 넣고 std::make_shared<t>를 사용하는 것을 추천</t></div><div><br /></div><div>- 동적 변수는 런타임 비용이 있음.</div><div>- 동적 변수의 메모리를 할당하기 위해서는 수천번의 메모리 접근이 필요할 때도 있음.</div><div> : 동적 변수 생성을 위해 메모리 할당 함수는 빈 메모리 블럭을 찾음.</div><div> . 빈 메모리 블록을 찾으면 블록을 제거한 뒤 제공</div><div> . 필요한 것보다 큰 블록을 찾으면 분할한 뒤 일부를 반환</div><div> : 이용 가능한 메모리 블록이 없다면 할당 함수는 큰 메모리 블럭을 추가로 얻기 위해 가용 메모리 시스템 풀에서 운영체제 커널을 고비용으로 호출</div><div> . 커널에서 사용하는 메모리는 RAM에 캐시되어 있을 수도 없을 수도 있음. 캐시되어 있지 않다면 지연 될 수 있음</div><div> : 빈 메모리 블록의 컬렉션은 프로그램의 모든 스레드가 공유하는 자원이며 메모리 블록 변경 사항은 스레드 세이프(thread-safe) 함</div><div> . 할당, 해제 함수를 자주 호출하면 하나 외 다른 스레드들이 대기하게 됨</div><div> : 동적 변수의 할당된 메모리를 해제할 때 반환된 블럭을 빈 메모리 컬렉션에 넣게 되지만 복잡함.</div><div> . 할당, 해제로 블록들의 크기가 작아지는 것을 방지하기 위해 해제된 메모리 블록을 인접한 메모리 블록과 합치려고 시도함. </div><div><br /></div><div><br /></div><div><b>동적 변수 사용 줄이기</b></div><div><br /></div><div>- 클래스 인스턴스를 정적으로 만들어라</div><div><i> ex) YourClass yourInstance("hahaha",111);</i></div><div><br /></div><div>- 클래스 멤버 변수를 정적으로 만들어라</div><div> : 클래스 멤버변수가 클래스 인스턴스라면 클래스 생성 시 멤버변수도 정적으로 생성되어 할당하는 비용을 줄일 수 있음.</div><div> : 클래스 생성 시 멤버 변수를 생성하기 위한 자원이 없어 동적으로 생성해야 하는 경우 두 단계초기화(two-part initialization)을 사용하라.</div><div><br /></div><div>- 배열의 크기가 정해져 있다면 std::vector 대신 std::array를 사용하라.</div><div> : std::array는 복사 생성할 수 있고 operator[]로 임의 접근 반복자와 첨자 지정을 제공함.</div><div><br /></div><div>- 저장공간이 커지면서 발생하는 재할당 비용을 줄이기 위해 스택에 큰 버퍼를 만들어라</div><div><br /></div><div>- 정적으로 초기화된 데이터가 연결 자료 구조라면 정적으로 구성하라.</div><div><br /></div><div>- 이진트리를 배열로 만들어라</div><div><br /></div><div>- std::deque 대신 원형 버퍼(<a href="http://bit.ly/b-buffer">http://bit.ly/b-buffer</a>)를 사용하라.</div><div><br /></div><div>- 변수 할당 비용을 줄이기 위해 new 대신 std::make_shared를 사용하라.</div><div><i> ex) std::shared_ptr<yourclass> p = std::make_shared<yourclass>("hahah",111);</yourclass></yourclass></i></div><div><i> auto p = std::make_shared<yourclass>("hahah",111);</yourclass></i></div><div><i><yourclass><br /></yourclass></i></div><div>- 동적 변수를 사용한다면 std::unique_ptr, std::shared_ptr을 사용하라.</div><div><br /></div><div><br /></div><div><b>동적 변수의 재할당 줄이기</b></div><div><br /></div><div>- 동적 변수를 미리 할당하여 재할당을 방지하라.</div><div> : 메모리할당 비용을 줄이기 위해 std::string, std::vector의 reserve(size_t n) 같은 함수로 적당히 공간을 확보하라.</div><div>- 반복문 바깥에서 동적 변수를 만들어라</div><div> : 반복문내의 변수는 할당/해제를 반복하므로 외부에 두고 clear()같은 함수를 사용하여 초기화 후 사용하라.</div><div><br /></div><div><br /></div><div><b>불필요한 복사 제거하기</b></div><div><br /></div><div>- 클래스의 대입 시(ClassA = ClassB)의 대입 연산자(Assignment operator)가 호출 됨. 이 때 클래스 멤버에 따라서 대입하는 비용이 상당히 커질 수 있음.</div><div>- 선언과 동시에 초기화 하는 문장(Foo a = b)의 경우 Foo가 클래스라면 복사생성자(Copy constructor)가 호출 됨. </div><div> : 대입 연산자와 복사 생성자는 하는일이 거의 동일하고 비용이 클 수 있어 최적화 시 다음상황에서 발생가능한지 확인해야 함.</div><div><br /></div><div>- 초기화 (생성자 호출)</div><div>- 대입 (대입 연산자 호출)</div><div>- 함수 인수 (함수의 인자/형식 인수로 전달되면서 이동 생성이나 복사 생성됨)</div><div>- 함수 반환 (이동 생성자나 복사 생성자를 호출)</div><div>- 표준 라이브러리 컨테이너에 항목을 삽입 (항목은 이동 생성이나 복사 생성됨)</div><div>- 벡터에 항목을 삽입 (벡터가 재할당 될 경우 모든 항목은 이동 생성이나 복사 생성됨)</div><div><br /></div><div>- 클래스 정의에서 원치 않는 복사 방지하기</div><div> : 클래스 인스턴스를 복사하는 비용이 많거나 복사를 원하지 않는다면 복사를 금지할 수 있음.</div><div> : 단 아래와 같이 복사를 금지한다면 표준 라이브러리 컨테이너 클래스 값으로 사용하지 못함.</div><div><br /></div><div><i>// C++ 11 이전 방법</i></div><div><i>class BigClass {</i></div><div><i>private :</i></div><div><i> BigClass(BigClass const&);</i></div><div><i> BigClass& operator=(BigClass const&);</i></div><div><i>public : </i></div><div><i>...</i></div><div><i>};</i></div><div><i><br /></i></div><div><i>// C++11 이후</i></div><div><i>class BigClass {</i></div><div><i>public </i></div><div><div><i> BigClass(BigClass const&) = delete;</i></div><div><i> BigClass& operator=(BigClass const&) = delete;</i></div></div><div><i> ...</i></div><div><i>};</i></div><div><br /></div><div><br /></div><div>- 함수 호출에서 복사 제거하기, </div><div> : 함수 인자로 넘겨지는 클래스 인스턴스의 경우 레퍼런스로 받아라. </div><div> : 내부에서 수정이 필요 없으면 const &, 수정이 필요하면 &</div><div> : 하지만 함수 내에서 레퍼런스값을 여러번 참조한다면 역참조(dereferencing)로 인한 비용이 더 커질 수 있음.</div><div><br /></div><div><i>포인터나 레퍼런스에서 값을 확인할 때를 <b>역참조</b>라 표현</i></div><div><a href="https://wikidocs.net/630" target="_blank"><i>https://wikidocs.net/630</i></a></div><div><a href="https://ko.coder.work/so/c%2B%2B/3249" target="_blank"><i>https://ko.coder.work/so/c%2B%2B/3249</i></a></div><div><br /></div><div><br /></div><div>- 함수 반환에서 복사 제거하기</div><div> : 함수에서 클래스 인스턴스를 리턴 시 반환값으로 복사 생성됨.</div><div> : 하지만 C++ 컴파일러에서는 복사 생략(copy elision), 반환값 최적화(return value optimization, RVO) 방법을 사용하지만 구체적인 조건에서만 가능함.</div><div> . 함수는 내부에서 생성된 객체를 반환해야 함.</div><div> . 함수에서 선언했던 반환 타입과 똑같은 타입이어야 함.</div><div> . 함수가 간단하고 제어 경로가 하나뿐이라면 컴파일러는 RVO를 수행할 가능성이 높음</div><div> : 그 외 방법으로는 출력용 매개변수(out parameter)를 사용하여 값을 반환하는 것도 방법임.</div><div><i> ex) <b>vector<int> </int></b>scalar_product(std::vector<int> const& v, int c) </int></i></div><div><i> => void scalar_product(std::vector<int> const& v, int c, <b>vector<int>& result</int></b>)</int></i></div><div><i> </i><br /></div><div><br /></div><div><i><b>RVO(Return Value Optimization)</b></i></div><div><a href="https://shaharmike.com/cpp/rvo/" target="_blank"><i>https://shaharmike.com/cpp/rvo/</i></a></div><div><i><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"> Output (note that<span style="background-color: rgba(255, 255, 255, 0.9); color: #515151; font-family: "PT Sans", Helvetica, Arial, sans-serif; font-size: 16px; font-style: italic;"> </span><code style="background-color: #f7f7f7; border-radius: 5px; border: 1px solid rgb(220, 220, 220); color: #515151; display: inline; font-family: "Source Code Pro", monospace, sans-serif; font-size: 16px; font-style: italic; margin: 0px; padding: 0px 2px;">-fno-elide-constructors</code><span style="background-color: rgba(255, 255, 255, 0.9); color: #515151; font-family: "PT Sans", Helvetica, Arial, sans-serif; font-size: 16px; font-style: italic;"> </span><span style="background-color: rgba(255, 255, 255, 0.9); color: #515151; font-family: "PT Sans", Helvetica, Arial, sans-serif; font-size: 16px; font-style: italic;">disables RVO in clang):</span><pre style="background-color: rgba(255, 255, 255, 0.9); color: #515151; font-size: 16px;"><code class="language-console" style="background-color: black; border-radius: 5px; border: 1px solid gray; color: #fffbde; display: block; font-family: "Source Code Pro", monospace, sans-serif; margin: 8px 0px; max-height: 800px; overflow: auto; padding: 5px;">$ clang++ -std=c++11 main.cpp && ./a.out
c'tor
d'tor
$ clang++ -std=c++11 -fno-elide-constructors main.cpp && ./a.out
c'tor
move c'tor
d'tor
move c'tor
d'tor
d'tor</code></pre></td></tr></tbody></table></i></div><div><i>RVO 적용과 미적용의 차이를 확실히 알 수 있다.</i></div><div><br /></div><div><br /></div><div>- COW(Copy On Write) 구현하기</div><div> : COW의 개념은 원본 객체와 복사한 객체 중 하나가 수정되기 전까지 객체가 동일하다는 것</div><div> 즉 초기에는 얕은 복사(shallow copy)를 하고 객체가 수정될 때까지 깊은 복사(deep copy)를 지연 시키는 것</div><div><br /></div><div><br /></div><div><b><i>COW(Copy On Write)</i></b></div><div><a href="https://en.m.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-on-write" target="_blank"><i>https://en.m.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-on-write</i></a></div><div><i>예시를 보여주고 있지만 주의점도 함께 설명하고 있다.</i></div><div><i><br /></i></div><div><a href="https://stackoverflow.com/a/1649046/13264783" target="_blank"><i>https://stackoverflow.com/a/1649046/13264783</i></a></div><div><blockquote><i><font size="2">n a multi-threaded environemnt (which is most of them nowadays) CoW is frequently a huge performance hit rather than a gain. And with careful use of const references, it's not much of a performance gain even in a single threaded environment. </font></i></blockquote><blockquote><i><font size="2">Additionally, as other people have pointed out, CoW strings are really tricky to implement, and it's easy to make mistakes. That coupled with their poor performance in threading situations makes me really question their usefulness in general. This becomes even more true once you start using C++11 move construction and move assignment. </font></i></blockquote></div><div><i>답변의 내용이 생각보다 부정적인 반응임. 구현하기 까다롭고 성능 개선도 크지 않을 수 있다고 함.</i></div><div><br /></div><div><br /></div><div><b>이동 문법 구현하기</b></div><div>책의 내용을 참고하자. 어렵지만 이 책(<a href="https://www.oreilly.com/library/view/effective-modern-c/9781491908419/" target="_blank">https://www.oreilly.com/library/view/effective-modern-c/9781491908419/</a>)도 참고하면 좋다.</div><div><br /></div><div><br /></div><div><b>평평한(flat) 자료구조</b><br />- 자료 구조 요소들이 인접한 저장 공간에 저장되었다면 자료구조가 평평하다고 표현함.</div><div>- 평평한 자료구조는 생성 시 포인터로 연결된 자료구조보다 메모리 관리자를 호출하는 횟수가 적음</div><div>- list, deque, map, unordered_map 자료구조는 동적 객체를 많이 만드는 반면 vector는 이보다 적게 만듬. 같은 big O 성능을 갖는다고 하더라도 평평한 자료구조가 가지는 장점이 많음.</div><div>- std::array, std::vector와 같은 평평한 자료구조는 list, map, unordered_map과 같은 노드 기반의 자료구조보다 메모리를 적게 차지함.</div><div>- 평평한 자료구조를 사용하면 스마트 포인터와 스마트 포인터가 가리키는 객체를 할당하는 런타임 비용을 없앨 수 있음.</div><div><div><br /></div></div></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-27765334945119409522020-06-04T04:49:00.001-07:002020-06-06T02:10:03.764-07:00C++ class 선언 시 소멸자, 복사 생성자(copy constructor), 이동 생성자(move constructor) 처리, The rule of three/five/zero<div>C++에서는 기본적인 내용인데 간과하기 쉬운게 class 생성시 member 변수의 형식에 따라서 생성자, 소멸자, 연산자를 처리해줘야 한다. 기본적인 생성자, 소멸자, 복사 생성자/할당 연산자, 이동 생성자/할당 연산자에 대해서는 아래 MSDN을 참고하면 자세하고 친절히 설명해준다.</div><div><br /></div><div><font size="1">- 생성자(constrctor), 소멸자(destructor)</font></div><div><font size="1"> : <a href="https://docs.microsoft.com/ko-kr/cpp/cpp/constructors-cpp?view=vs-2019">https://docs.microsoft.com/ko-kr/cpp/cpp/constructors-cpp?view=vs-2019</a></font></div><div><font size="1"> : <a href="https://docs.microsoft.com/ko-kr/cpp/cpp/destructors-cpp?view=vs-2019">https://docs.microsoft.com/ko-kr/cpp/cpp/destructors-cpp?view=vs-2019</a></font></div><div><font size="1"><br /></font></div><div><font size="1">- 복사 생성자(copy constructor), 복사 할당 연산자(copy assign operator)</font></div><div><font size="1"> : <a href="https://docs.microsoft.com/ko-kr/cpp/cpp/copy-constructors-and-copy-assignment-operators-cpp?view=vs-2019">https://docs.microsoft.com/ko-kr/cpp/cpp/copy-constructors-and-copy-assignment-operators-cpp?view=vs-2019</a></font></div><div><font size="1"><br /></font></div><div><font size="1">- 이동 생성자(move constructor), 이동 할당 연산자(move assignment operator)</font></div><div><font size="1"> : <a href="https://docs.microsoft.com/ko-kr/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=vs-2019">https://docs.microsoft.com/ko-kr/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=vs-2019</a></font></div><div><br /></div><div><br /></div><div>예를 들어 class member 변수가 pointer와 같이 복사, 이동 시 관리되지 않는 변수 형식이라면 class가 생성, 소멸, 복사, 이동 시 해당 member 변수가 정상적으로 할당, 삭제, 복사, 이동 될 수 있도록 해줘야 한다.</div><div><br /></div><div>왜나면 C++에서는 특정 조건에 따라 컴파일러가 class의 생성자, 복사 생성자, 복사 할당 연산자, 소멸자를 자동으로 생성하게 되어 의도치 않게 member 변수가 복사, 이동 될 수 있음.</div><div><a href="https://docs.microsoft.com/ko-kr/cpp/cpp/explicitly-defaulted-and-deleted-functions?view=vs-2019">https://docs.microsoft.com/ko-kr/cpp/cpp/explicitly-defaulted-and-deleted-functions?view=vs-2019</a></div><div><br /></div><div>"C++ 얕은복사 vs 깊은복사" 검색어나 "C++ shallow copy vs deep copy" 검색어로 검색하면 관련 글들이 꽤 나온다.</div><div><br /></div><div><br /></div><div>그래서 C++ class 선언과 관련된 <b>The rule of three/five/zero </b>같은 용어가 있음.</div><div><a href="https://en.cppreference.com/w/cpp/language/rule_of_three">https://en.cppreference.com/w/cpp/language/rule_of_three</a></div><div><br /></div><div>간단히 말하면 class 선언 시 member 변수의 처리에 따라 3개, 5개, 0개의 생성자, 연산자를 정의하라는 것이고 간략히 내용을 발췌하면 다음과 같음.</div><div><br /></div><div>아래 Rule of three 코드에서 복사 시 제대로 관리되지 않는 char* 형의 cstring member 변수가 있다.</div><div>만약 복사 생성자를 정의하지 않아 컴파일러가 복사 생성자를 만든다면 해당 member 변수는 복사 시 얕은 복사(shallow copy)가 되어 member 변수의 pointer 주소만 복사되어 두 class instance는 동일한 메모리를 바라보게 된다. 프로그램 실행 중 한 instance가 소멸되면 다른 instance의 변수가 영향을 받는다.</div><div><br /></div><div>그래서 아래 코드에서는 3개(복사 생성자(copy constructor), 복사 할당 연산자(copy assignment), 소멸자) member 함수를 정의 하여 깊은 복사(deep copy)를 하여 복사된 class instance가 복사한 class instance와 다른 저장공간의 member 변수를 가지도록 한다.</div><div><br /></div><div>일반적으로 관리되지 않는 member 변수 특히나 char* 형식의 단순 문자열을 가지고 있는 경우 아래와 같이 정의하여 처리한다.</div><div><br /></div><div><b>Rule of three</b></div><div><br /></div><div><pre class="de1" style="background: none rgb(249, 249, 249); border-radius: 5px; border: 0px none white; font-size: 12.8px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.2em; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 0px; vertical-align: top; width: 55em;"><span class="kw1" style="color: #0000dd;">class</span> rule_of_three
<span class="br0" style="color: green;">{</span>
<span class="kw4" style="color: blue;">char</span><span class="sy2" style="color: #000040;">*</span> cstring<span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// raw pointer used as a handle to a dynamically-allocated memory block</span>
<span class="kw4" style="color: blue;">void</span> init<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> <span class="kw4" style="color: blue;">char</span><span class="sy2" style="color: #000040;">*</span> s<span class="br0" style="color: green;">)</span>
<span class="br0" style="color: green;">{</span>
<a href="http://en.cppreference.com/w/cpp/types/size_t" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1" style="color: navy;">=</span> <a href="http://en.cppreference.com/w/cpp/string/byte/strlen" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1142">std::<span class="me2">strlen</span></span></a><span class="br0" style="color: green;">(</span>s<span class="br0" style="color: green;">)</span> <span class="sy2" style="color: #000040;">+</span> <span class="nu0" style="color: navy;">1</span><span class="sy4" style="color: teal;">;</span>
cstring <span class="sy1" style="color: navy;">=</span> new <span class="kw4" style="color: blue;">char</span><span class="br0" style="color: green;">[</span>n<span class="br0" style="color: green;">]</span><span class="sy4" style="color: teal;">;</span>
<a href="http://en.cppreference.com/w/cpp/string/byte/memcpy" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1156">std::<span class="me2">memcpy</span></span></a><span class="br0" style="color: green;">(</span>cstring, s, n<span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// populate</span>
<span class="br0" style="color: green;">}</span>
<span class="kw1" style="color: #0000dd;">public</span><span class="sy4" style="color: teal;">:</span>
rule_of_three<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> <span class="kw4" style="color: blue;">char</span><span class="sy2" style="color: #000040;">*</span> s <span class="sy1" style="color: navy;">=</span> <span class="st0" style="color: green;">""</span><span class="br0" style="color: green;">)</span> <span class="br0" style="color: green;">{</span> init<span class="br0" style="color: green;">(</span>s<span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span> <span class="br0" style="color: green;">}</span>
~rule_of_three<span class="br0" style="color: green;">(</span><span class="br0" style="color: green;">)</span>
<span class="br0" style="color: green;">{</span>
delete<span class="br0" style="color: green;">[</span><span class="br0" style="color: green;">]</span> cstring<span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// deallocate</span>
<span class="br0" style="color: green;">}</span>
rule_of_three<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> rule_of_three<span class="sy3" style="color: #000040;">&</span> other<span class="br0" style="color: green;">)</span> <span class="co1" style="color: #909090;">// copy constructor</span>
<span class="br0" style="color: green;">{</span>
init<span class="br0" style="color: green;">(</span>other.<span class="me1">cstring</span><span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span>
<span class="br0" style="color: green;">}</span>
rule_of_three<span class="sy3" style="color: #000040;">&</span> operator<span class="sy1" style="color: navy;">=</span><span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> rule_of_three<span class="sy3" style="color: #000040;">&</span> other<span class="br0" style="color: green;">)</span> <span class="co1" style="color: #909090;">// copy assignment</span>
<span class="br0" style="color: green;">{</span>
<span class="kw1" style="color: #0000dd;">if</span><span class="br0" style="color: green;">(</span>this <span class="sy3" style="color: #000040;">!</span><span class="sy1" style="color: navy;">=</span> <span class="sy3" style="color: #000040;">&</span>other<span class="br0" style="color: green;">)</span> <span class="br0" style="color: green;">{</span>
delete<span class="br0" style="color: green;">[</span><span class="br0" style="color: green;">]</span> cstring<span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// deallocate</span>
init<span class="br0" style="color: green;">(</span>other.<span class="me1">cstring</span><span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span>
<span class="br0" style="color: green;">}</span>
<span class="kw1" style="color: #0000dd;">return</span> <span class="sy2" style="color: #000040;">*</span>this<span class="sy4" style="color: teal;">;</span>
<span class="br0" style="color: green;">}</span>
<span class="br0" style="color: green;">}</span><span class="sy4" style="color: teal;">;</span></pre></div><div><br /></div><div><br /></div><div>아래 코드에서는 동일한 상황이지만 class instance가 이동 생성자(move constructor), 이동 할당 연산자(move assignment operator)가 사용되는 상황을 처리하기 위해 5개(이동 생성자(move constructor), 이동 할당 연산자(move assignment operator), 복사 생성자(copy constructor), 복사 할당 연산자(copy assignment), 소멸자) member 함수를 정의하였음.</div><div><br /></div><div>예제의 swap 함수를 보면 알겠지만 할당된 메모리양이 많은 char* member 변수를 가지고 있는 경우 class instance 이동 시 performance를 고려하고자 이동 생성자, 할당 연산자를 정의하는 경우가 있다고 함.</div><div><br /></div><div><b>Rule of five</b></div><div><b><br /></b></div><div><pre class="de1" style="background: none rgb(249, 249, 249); border-radius: 5px; border: 0px none white; font-size: 12.8px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.2em; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 0px; vertical-align: top; width: 55em;"><span class="kw1" style="color: #0000dd;">class</span> rule_of_five
<span class="br0" style="color: green;">{</span>
<span class="kw4" style="color: blue;">char</span><span class="sy2" style="color: #000040;">*</span> cstring<span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// raw pointer used as a handle to a dynamically-allocated memory block</span>
<span class="kw1" style="color: #0000dd;">public</span><span class="sy4" style="color: teal;">:</span>
rule_of_five<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> <span class="kw4" style="color: blue;">char</span><span class="sy2" style="color: #000040;">*</span> s <span class="sy1" style="color: navy;">=</span> <span class="st0" style="color: green;">""</span><span class="br0" style="color: green;">)</span>
<span class="sy4" style="color: teal;">:</span> cstring<span class="br0" style="color: green;">(</span>nullptr<span class="br0" style="color: green;">)</span>
<span class="br0" style="color: green;">{</span>
<span class="kw1" style="color: #0000dd;">if</span> <span class="br0" style="color: green;">(</span>s<span class="br0" style="color: green;">)</span> <span class="br0" style="color: green;">{</span>
<a href="http://en.cppreference.com/w/cpp/types/size_t" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw100">std::<span class="me2">size_t</span></span></a> n <span class="sy1" style="color: navy;">=</span> <a href="http://en.cppreference.com/w/cpp/string/byte/strlen" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1142">std::<span class="me2">strlen</span></span></a><span class="br0" style="color: green;">(</span>s<span class="br0" style="color: green;">)</span> <span class="sy2" style="color: #000040;">+</span> <span class="nu0" style="color: navy;">1</span><span class="sy4" style="color: teal;">;</span>
cstring <span class="sy1" style="color: navy;">=</span> new <span class="kw4" style="color: blue;">char</span><span class="br0" style="color: green;">[</span>n<span class="br0" style="color: green;">]</span><span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// allocate</span>
<a href="http://en.cppreference.com/w/cpp/string/byte/memcpy" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1156">std::<span class="me2">memcpy</span></span></a><span class="br0" style="color: green;">(</span>cstring, s, n<span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// populate </span>
<span class="br0" style="color: green;">}</span>
<span class="br0" style="color: green;">}</span>
~rule_of_five<span class="br0" style="color: green;">(</span><span class="br0" style="color: green;">)</span>
<span class="br0" style="color: green;">{</span>
delete<span class="br0" style="color: green;">[</span><span class="br0" style="color: green;">]</span> cstring<span class="sy4" style="color: teal;">;</span> <span class="co1" style="color: #909090;">// deallocate</span>
<span class="br0" style="color: green;">}</span>
rule_of_five<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> rule_of_five<span class="sy3" style="color: #000040;">&</span> other<span class="br0" style="color: green;">)</span> <span class="co1" style="color: #909090;">// copy constructor</span>
<span class="sy4" style="color: teal;">:</span> rule_of_five<span class="br0" style="color: green;">(</span>other.<span class="me1">cstring</span><span class="br0" style="color: green;">)</span>
<span class="br0" style="color: green;">{</span><span class="br0" style="color: green;">}</span>
rule_of_five<span class="br0" style="color: green;">(</span>rule_of_five<span class="sy3" style="color: #000040;">&&</span> other<span class="br0" style="color: green;">)</span> <span class="kw1" style="color: #0000dd;">noexcept</span> <span class="co1" style="color: #909090;">// move constructor</span>
<span class="sy4" style="color: teal;">:</span> cstring<span class="br0" style="color: green;">(</span><a href="http://en.cppreference.com/w/cpp/utility/exchange" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1115">std::<span class="me2">exchange</span></span></a><span class="br0" style="color: green;">(</span>other.<span class="me1">cstring</span>, nullptr<span class="br0" style="color: green;">)</span><span class="br0" style="color: green;">)</span>
<span class="br0" style="color: green;">{</span><span class="br0" style="color: green;">}</span>
rule_of_five<span class="sy3" style="color: #000040;">&</span> operator<span class="sy1" style="color: navy;">=</span><span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> rule_of_five<span class="sy3" style="color: #000040;">&</span> other<span class="br0" style="color: green;">)</span> <span class="co1" style="color: #909090;">// copy assignment</span>
<span class="br0" style="color: green;">{</span>
<span class="kw1" style="color: #0000dd;">return</span> <span class="sy2" style="color: #000040;">*</span>this <span class="sy1" style="color: navy;">=</span> rule_of_five<span class="br0" style="color: green;">(</span>other<span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span>
<span class="br0" style="color: green;">}</span>
rule_of_five<span class="sy3" style="color: #000040;">&</span> operator<span class="sy1" style="color: navy;">=</span><span class="br0" style="color: green;">(</span>rule_of_five<span class="sy3" style="color: #000040;">&&</span> other<span class="br0" style="color: green;">)</span> <span class="kw1" style="color: #0000dd;">noexcept</span> <span class="co1" style="color: #909090;">// move assignment</span>
<span class="br0" style="color: green;">{</span>
<a href="http://en.cppreference.com/w/cpp/algorithm/swap" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1596">std::<span class="me2">swap</span></span></a><span class="br0" style="color: green;">(</span>cstring, other.<span class="me1">cstring</span><span class="br0" style="color: green;">)</span><span class="sy4" style="color: teal;">;</span>
<span class="kw1" style="color: #0000dd;">return</span> <span class="sy2" style="color: #000040;">*</span>this<span class="sy4" style="color: teal;">;</span>
<span class="br0" style="color: green;">}</span>
<span class="co1" style="color: #909090;">// alternatively, replace both assignment operators with </span>
<span class="co1" style="color: #909090;">// rule_of_five& operator=(rule_of_five other) noexcept</span>
<span class="co1" style="color: #909090;">// {</span>
<span class="co1" style="color: #909090;">// std::swap(cstring, other.cstring);</span>
<span class="co1" style="color: #909090;">// return *this;</span>
<span class="co1" style="color: #909090;">// }</span>
<span class="br0" style="color: green;">}</span><span class="sy4" style="color: teal;">;</span></pre></div><div><br /></div><div>class의 member 변수가 복사, 이동 시 관리되는 경우라면 컴파일러가 생성하는 default 생성자, 연산자를 사용하도록 지정한 예제 코드들이다. 처음 코드 처럼 아무것도 선언하지 않거나 두번째 코드 처럼 default로 지정해도 class 생성, 복사, 이동 시 처리되는 결과는 동일한다.</div><div><br /></div><div>C++로 개발하고 파일 operation 처리와 같이 byte stream을 처리해야 하는 경우가 아닌 단순 문자열을 처리하는 상황, performance가 critical한 요소가 아니라면 std::string을 사용하는게 당연해 보인다.</div><div><br /></div><div><b>Rule of zero</b></div><div><br /></div><div><pre class="de1" style="background: none rgb(249, 249, 249); border-radius: 5px; border: 0px none white; font-size: 12.8px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.2em; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 0px; vertical-align: top; width: 55em;"><span class="kw1" style="color: #0000dd;">class</span> rule_of_zero
<span class="br0" style="color: green;">{</span>
<a href="http://en.cppreference.com/w/cpp/string/basic_string" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1227">std::<span class="me2">string</span></span></a> cppstring<span class="sy4" style="color: teal;">;</span>
<span class="kw1" style="color: #0000dd;">public</span><span class="sy4" style="color: teal;">:</span>
rule_of_zero<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> <a href="http://en.cppreference.com/w/cpp/string/basic_string" style="background: none; color: #003080; text-decoration-line: none;"><span class="kw1227">std::<span class="me2">string</span></span></a><span class="sy3" style="color: #000040;">&</span> arg<span class="br0" style="color: green;">)</span> <span class="sy4" style="color: teal;">:</span> cppstring<span class="br0" style="color: green;">(</span>arg<span class="br0" style="color: green;">)</span> <span class="br0" style="color: green;">{</span><span class="br0" style="color: green;">}</span>
<span class="br0" style="color: green;">}</span><span class="sy4" style="color: teal;">;</span></pre></div><div><br /></div><div><pre class="de1" style="background: none rgb(249, 249, 249); border-radius: 5px; border: 0px none white; font-size: 12.8px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 1.2em; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 0px; vertical-align: top; width: 55em;"><span class="kw1" style="color: #0000dd;">class</span> base_of_five_defaults
<span class="br0" style="color: green;">{</span>
<span class="kw1" style="color: #0000dd;">public</span><span class="sy4" style="color: teal;">:</span>
base_of_five_defaults<span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> base_of_five_defaults<span class="sy3" style="color: #000040;">&</span><span class="br0" style="color: green;">)</span> <span class="sy1" style="color: navy;">=</span> <span class="kw1" style="color: #0000dd;">default</span><span class="sy4" style="color: teal;">;</span>
base_of_five_defaults<span class="br0" style="color: green;">(</span>base_of_five_defaults<span class="sy3" style="color: #000040;">&&</span><span class="br0" style="color: green;">)</span> <span class="sy1" style="color: navy;">=</span> <span class="kw1" style="color: #0000dd;">default</span><span class="sy4" style="color: teal;">;</span>
base_of_five_defaults<span class="sy3" style="color: #000040;">&</span> operator<span class="sy1" style="color: navy;">=</span><span class="br0" style="color: green;">(</span><span class="kw4" style="color: blue;">const</span> base_of_five_defaults<span class="sy3" style="color: #000040;">&</span><span class="br0" style="color: green;">)</span> <span class="sy1" style="color: navy;">=</span> <span class="kw1" style="color: #0000dd;">default</span><span class="sy4" style="color: teal;">;</span>
base_of_five_defaults<span class="sy3" style="color: #000040;">&</span> operator<span class="sy1" style="color: navy;">=</span><span class="br0" style="color: green;">(</span>base_of_five_defaults<span class="sy3" style="color: #000040;">&&</span><span class="br0" style="color: green;">)</span> <span class="sy1" style="color: navy;">=</span> <span class="kw1" style="color: #0000dd;">default</span><span class="sy4" style="color: teal;">;</span>
<span class="kw1" style="color: #0000dd;">virtual</span> ~base_of_five_defaults<span class="br0" style="color: green;">(</span><span class="br0" style="color: green;">)</span> <span class="sy1" style="color: navy;">=</span> <span class="kw1" style="color: #0000dd;">default</span><span class="sy4" style="color: teal;">;</span>
<span class="br0" style="color: green;">}</span><span class="sy4" style="color: teal;">;</span></pre></div><div><br /></div><div><br /></div><div>하지만 컴파일러가 자동으로 생성하는 것을 고려한다면 class 선언이 다음 규칙을 따르도록 해야 한다. 괜히 어설프가 일부 생성자, 연산자를 정의하면 자동으로 생성되지 않을 수 있어 곤란해질 수 있다.</div><div><br /></div><div><a href="https://docs.microsoft.com/ko-kr/cpp/cpp/explicitly-defaulted-and-deleted-functions?view=vs-2019#benefits-of-explicitly-defaulted-and-deleted-functions">https://docs.microsoft.com/ko-kr/cpp/cpp/explicitly-defaulted-and-deleted-functions?view=vs-2019#benefits-of-explicitly-defaulted-and-deleted-functions</a></div><div><br /></div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"><i><font size="2"> 따라서 단순 형식에는 편리하지만 복합 형식은 종종 하나 이상의 특수 멤버 함수 자체를 정의하므로 다른 특수 멤버 함수가 자동으로 생성되지 않도록 할 수 있습니다.<span style="background-color: white; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif;"> </span><span data-ttu-id="f1edb-110" style="box-sizing: inherit; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif; outline-color: inherit;">실제로는 다음과 같습니다.</span></font></i><ul style="background-color: white; box-sizing: inherit; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif; list-style: none; margin: 16px 0px 16px 38px; outline-color: inherit; padding: 0px;"><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-111" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">생성자가 명시적으로 선언된 경우 기본 생성자가 자동으로 생성되지 않습니다.</font></i></span></p></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-112" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">가상 소멸자가 명시적으로 선언된 경우 기본 소멸자가 자동으로 생성되지 않습니다.</font></i></span></p></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-113" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">이동 생성자 혹은 이동 할당 연산자가 명시적으로 선언된 경우 다음과 같습니다.</font></i></span></p><ul style="box-sizing: inherit; list-style: none; margin: 0px 0px 0px 20px; outline-color: inherit; padding: 0px;"><li style="box-sizing: inherit; list-style: outside none circle; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-114" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">복사 생성자가 자동으로 생성되지 않습니다.</font></i></span></p></li><li style="box-sizing: inherit; list-style: outside none circle; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-115" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">복사 할당 연산자가 자동으로 생성되지 않습니다.</font></i></span></p></li></ul></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-116" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">복사 생성자, 복사 할당 연산자, 이동 생성자, 이동 할당 연산자 또는 소멸자가 명시적으로 선언된 경우 다음과 같습니다.</font></i></span></p><ul style="box-sizing: inherit; list-style: none; margin: 0px 0px 0px 20px; outline-color: inherit; padding: 0px;"><li style="box-sizing: inherit; list-style: outside none circle; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-117" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">이동 생성자가 자동으로 생성되지 않습니다.</font></i></span></p></li><li style="box-sizing: inherit; list-style: outside none circle; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><p style="box-sizing: inherit; margin: 1rem 0px 0px; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-118" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">이동 할당 연산자가 자동으로 생성되지 않습니다.</font></i></span></p></li></ul></li></ul><div class="alert is-info" style="border-radius: 6px; border: 1px solid; box-sizing: inherit; color: #171717; font-family: "segoe ui", segoeui, "helvetica neue", helvetica, arial, sans-serif; margin-top: 1rem; outline-color: var(--text); overflow-wrap: break-word; padding: 1rem; position: relative; transition: all 0.5s ease-in 0s, all 0.5s ease-in 0s; word-break: break-word;"><p class="alert-title" style="box-sizing: inherit; color: var(--info-dark); font-weight: 600; margin: 0px; max-width: 100%; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><i><font size="2"><span aria-hidden="true" class="docon docon-status-error-outline" style="-webkit-font-smoothing: antialiased; box-sizing: inherit; direction: ltr; display: inline-block; font-family: docons; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 400; line-height: 16px; outline-color: inherit; speak: none; text-align: center;"></span> 참고</font></i></p><p style="box-sizing: inherit; margin: 1rem 0px 0px; max-width: 100%; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-119" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">또한 C++ 11 표준은 다음 추가 규칙을 지정합니다.</font></i></span></p><ul style="box-sizing: inherit; line-height: 1.8; list-style: none; margin: 16px 0px 0px 38px; max-width: 100%; outline-color: inherit; padding: 0px;"><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><span data-ttu-id="f1edb-120" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">복사 생성자나 소멸자가 명시적으로 선언된 경우 복사 할당 연산자가 자동으로 생성되지 않습니다.</font></i></span></li><li style="box-sizing: inherit; list-style: outside none disc; margin: 0px; outline-color: inherit; outline-style: initial; outline-width: 0px; padding: 0px;"><span data-ttu-id="f1edb-121" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">복사 할당 연산자나 소멸자가 명시적으로 선언된 경우 복사 생성자가 자동으로 생성되지 않습니다.</font></i></span></li></ul><p style="box-sizing: inherit; margin: 1rem 0px 0px; max-width: 100%; outline-color: inherit; overflow-wrap: break-word; padding: 0px;"><span data-ttu-id="f1edb-122" style="box-sizing: inherit; outline-color: inherit;"><i><font size="2">두 경우 모두 Visual Studio에서는 필요한 함수가 암시적으로 자동 생성되며 경고를 생성하지 않습니다.</font></i></span></p></div></td></tr></tbody></table><br /></div><div>참고로 아래 rule 같이 하나를 정의할 거면 모두 정의하던지 delete 처리하라던지 조언 하기도 함.</div><div><br /></div><div><b>C.21: If you define or =delete any default operation, define or =delete them all</b></div><div><a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all">https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all</a></div><div><br /></div><div><a href="http://scottmeyers.blogspot.com/2014/03/a-concern-about-rule-of-zero.html">http://scottmeyers.blogspot.com/2014/03/a-concern-about-rule-of-zero.html</a></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-2571309229232089052020-05-28T22:23:00.002-07:002020-05-28T22:27:34.255-07:00C++ 최적화 책, 4장 문자열 최적화 <br /><div>C++ 최적화 : 최고 성능을 구현하는 10가지 검증된 기법 </div><div>커트 건서로스 저/옥찬호 역/박수현 감수 | 한빛미디어</div><div><a href="http://www.yes24.com/Product/Goods/74971458?scode=032" target="_blank">http://www.yes24.com/Product/Goods/74971458?scode=032</a></div><div><br /></div><div>책을 보고 간략히 정리하려고 함.</div><div>오랜만에 보는 괜찮은 c++ 언어 서적이다.</div><div>"Effective Modern C++" 을 보다가 내용과 번역에 질려버리고 </div><div>"모던 C++ 입문" 을 봤었는데 그 책의 저자가 이 책을 번역하였음.</div><div><br /></div><div>책의 전반적인 내용은 최적화라는 관점에서 가능한 모든 방법을 소개하는 것 같다.</div><div>최적화의 방법이 정도가 없어 일반적인 내용, 저자의 경험과 테스트를 통해서 알게 된 내용들을 소개하고 있다. </div><div>C++ 문법, skill을 가르치는 것은 아니고 효율적인 코드를 작성하기 위해 알아야 하는 내용과 방법을 제시한다.</div><div><br /></div><div><br /></div><div><br /></div><div><b>1장 최적화란</b></div><div><br /></div><div>다음 권고 사항들로 정리할 수 있어 보인다.</div><div>- 더 좋은 컴파일러를 사용하고 최적화 설정을 사용하세요.</div><div>- 최적의 알고리즘을 사용하세요.</div><div>- 더 좋은 라이브러리를 더 잘 사용하세요.</div><div>- 메모리 할당을 줄이세요.</div><div>- 복사를 줄이세요.</div><div>- 계산을 제거하세요.</div><div>- 최적의 자료구조를 사용하세요.</div><div>- 동시성을 증가시키세요.</div><div>- 메모리 관리를 최적화하세요.</div><div><br /></div><div>책의 목차를 보면 알겠지만 위 내용을 책에서 나눠 설명하고 있고</div><div>각 내용을 간략히 정리하는 챕터이다. c++ 언어 특성과 관련이 있는 팁도 있지만, 프로그래밍 시 일반적으로 알아야 하고 적용할 수 있는 조언이 대부분이라 유익하다.</div><div><br /></div><div><br /></div><div><br /></div><div><b>4장 문자열 최적화</b></div><div><br /></div><div>(오라일리에서 제공하는 online book 페이지입니다.</div><div>아래 내용, 코드는 모드 아래 출처에서 발췌하였다.)</div><div><a href="https://www.oreilly.com/library/view/optimized-c/9781491922057/ch04.html" target="_blank">https://www.oreilly.com/library/view/optimized-c/9781491922057/ch04.html</a></div><div><br /></div><div>std::string은 저장소를 동적으로 할당합니다.</div><div>문자열이 추가되면서 문자열보다 저장소가 훨씬 크게 할당할 수 있어 메모리가 낭비될 수 있다고 합니다.</div><div>문자열은 값처럼 동작하여 문자열 사용 시 복사가 많이 일어날 수밖에 없다고 합니다. </div><div><br /></div><div>책에서는 아래 함수를 예시로 최적화를 진행합니다.</div><div><br /></div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"><pre data-code-language="c++" data-type="programlisting" style="-webkit-font-smoothing: antialiased; background-color: #fbfbfb; border-bottom: 1px solid rgb(221, 221, 221); border-image: initial; border-left: 0px; border-right: 0px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #3d3b49; font-family: "droid sans mono", courier, monospace; font-kerning: normal; font-size: 16px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-ligatures: none; font-variant-numeric: inherit; hyphens: none; line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; overflow-wrap: initial; overflow: auto hidden; padding: 1em 2em; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline; word-break: keep-all;"><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">::</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">remove_ctrl</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">::</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code> <code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">{</code>
<code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">::</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code>
<code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">for</code> <code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="kt" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #007788; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">int</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code class="mi" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #ff6600; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">0</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"><</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">length</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">();</code> <code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">++</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code> <code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">{</code>
<code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">if</code> <code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">[</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">]</code> <code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">>=</code> <code class="mh" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #ff6600; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">0x20</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code>
<code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code> <code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code> <code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">[</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">];</code>
<code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">}</code>
<code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">return</code> <code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code> </pre><span style="background-color: #fbfbfb; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-variant-ligatures: inherit; font-weight: inherit; text-align: inherit;">}</span> </td></tr></tbody></table><br /></div><div>그냥 봐도 수정할 것이 많아 보임...</div><div><br /></div><div>(임시 문자열 객체 생성 제거) </div><div>result = result + s[i] 에서 </div><div>s[i]를 더한 새로운 result를 저장하기 위해 </div><div>생성된 임시 문자열을 </div><div> result += s[i];</div><div>로 변경하여 임시 문자열이 생성되지 않게 하여 성능을 개선합니다.</div><div><br /></div><div>(문자열 저장 공간 예약)</div><div>result에 저장하는 문자열은 최대 s의 크기이므로</div><div>result.reserve(s.length())를 호출하여</div><div>미리 저장 공간을 예약하여 </div><div>result 값이 증가함에 따라 저장 공간 확보 시도를 줄여 성능을 개선합니다. </div><div><br /></div><div>(함수 인자 복사를 제거)</div><div>std::string s로 넘겨지는 인자의 복사(pass by value)를 제거하기 위해</div><div>std::string const& s</div><div>로 변경하여 인자를 레퍼런스(pass by reference)로 받아</div><div>불필요한 임시객체 생성&복사를 방지하여 성능을 개선하려고 하였지만</div><div>s의 포인터 역참조(포인터의 값을 사용하기 위해 포인터가 가리키는 주소를 접근)로 인해 성능이 저하 되었습니다. </div><div><br /></div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"><pre data-code-language="c++" data-type="programlisting" style="-webkit-font-smoothing: antialiased; background-color: #fbfbfb; border-bottom: 1px solid rgb(221, 221, 221); border-image: initial; border-left: 0px; border-right: 0px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #3d3b49; font-family: "droid sans mono", courier, monospace; font-kerning: normal; font-size: 16px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-ligatures: none; font-variant-numeric: inherit; hyphens: none; line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; overflow-wrap: initial; overflow: auto hidden; padding: 1em 2em; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline; word-break: keep-all;"><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">remove_ctrl_ref_args</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><strong style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; margin: 0px; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">const</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">&</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code></strong><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">{</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">reserve</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">length</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">for</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="kt" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #007788; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">int</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code class="mi" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #ff6600; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">0</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"><</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">length</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">{</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">if</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">[</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">]</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">></code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="mh" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #ff6600; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">0x20</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">[</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">i</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">]</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">}</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">return</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code></pre><span style="background-color: #fbfbfb; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-variant-ligatures: inherit; font-weight: inherit; text-align: inherit;">}</span> </td></tr></tbody></table><br /></div><div><br /></div><div>(반복자로 포인터 역참조 제거)</div><div>역참조를 제거 하기 위해 s[i] 를 </div><div>iterator로 사용하여 성능을 개선할 수 있었습니다.</div><div>함께 loop을 반복할 때 마다 종료 조건에서의 간접 참조 비용을 줄이기 위해 </div><div>it != s.end() 대신 s.end()를 캐싱하여 it != end로 변경하여 성능을 개선합니다. </div><div> </div><div><table border="1" bordercolor="#888" cellspacing="0" style="border-collapse: collapse; border-color: rgb(136, 136, 136); border-width: 1px;"><tbody><tr><td style="min-width: 60px;"><pre data-code-language="c++" data-type="programlisting" style="-webkit-font-smoothing: antialiased; background-color: #fbfbfb; border-bottom: 1px solid rgb(221, 221, 221); border-image: initial; border-left: 0px; border-right: 0px; border-top: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #3d3b49; font-family: "droid sans mono", courier, monospace; font-kerning: normal; font-size: 16px; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-ligatures: none; font-variant-numeric: inherit; hyphens: none; line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; overflow-wrap: initial; overflow: auto hidden; padding: 1em 2em; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline; word-break: keep-all;"><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">remove_ctrl_ref_args_it</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><strong style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; margin: 0px; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">const</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">&</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code></strong><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">{</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">std</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">:</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">string</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">reserve</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">length</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><strong style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; line-height: inherit; margin: 0px; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">for</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">auto</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">it</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">begin</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">,</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">end</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">s</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">.</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">end</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">it</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">!</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">end</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">it</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">{</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">if</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">(</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">*</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">it</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">></code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="mh" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #ff6600; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">0x20</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">)</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">+</code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">=</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="o" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #555555; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">*</code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">it</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">}</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono bold", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">
</code></strong><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="err" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #aa0000; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="k" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #006699; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: bold; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">return</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code><code class="n" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: #000088; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">result</code><code class="p" style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; color: black; font-family: inherit !important; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: 1.5em; margin: 0.75em 0px 1.25em; overflow-wrap: break-word; padding: 0px; text-align: inherit; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;">;</code><code style="-webkit-font-smoothing: antialiased; border: 0px; box-sizing: border-box; font-family: "ubuntu mono", monospace; font-kerning: normal; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; hyphens: none; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; text-rendering: optimizelegibility; text-size-adjust: 100%; vertical-align: baseline;"> </code></pre><span style="background-color: #fbfbfb; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-variant-ligatures: inherit; font-weight: inherit; text-align: inherit;">}</span> </td></tr></tbody></table><br /></div><div><br /></div><div>(반환된 문자열 값의 복사 제거하기)</div><div>반환되는 std::string이 복사되게 되어</div><div>이를 생략하기 위해 함수의 참조 인자(std::string& result)로 변경하여 성능을 개선합니다.</div><div><br /></div><div>마지막으로 속도가 중요한 경우에 사용할 수 있는</div><div>C 스타일 문자열을 사용하여 성능을 개선합니다. </div><div><br /></div><div>책에서는 성능 요약을 표로 정리했는데 릴리즈 빌드로 24.8 마이크로 걸리던 코드를 1.02 마이크로초로 줄이고 c 스타일 문자열을 사용하여 0.15 마이크로초까지 성능을 개선했다.</div><div><br /></div><div>그 외 성능 개선을 위한 다른 방법들을 설명하고 있고 </div><div>다음의 방법으로 개선을 시도할 수 있다고 말하고 있음. </div><div>- 더 좋은 알고리즘 사용</div><div>- 저 좋은 컴파일러 사용</div><div>- 더 좋은 문자열 라이브러리 사용</div><div>- 더 좋은 할당자 사용</div><div><br /></div><div><br /></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-63832969611940386182020-05-05T20:09:00.000-07:002020-05-05T20:09:04.715-07:00Android Room을 사용하여 DB에 데이터 저장일반적으로 android에서 app을 만들 때 DB 사용은 필요함.<br />
<br />
기존에는 SQLite를 사용하여 data class를 읽고 쓰고 할 수 있는 Generic DB access hander 같은 것을 만들었는데 이제는 Android에서 이를 지원한다.<br />
<br />
Android Jetpack에서 Room이 여기에 해당되며<br />
SQL의 Abstraction layer로서 쉽게 DB를 사용 가능하도록 해준다.<br />
단 코드 기반 Room class 생성으로 로직 수정 시 빌드가 필요하다.<br />
<br />
<h3>
Room 개요</h3>
<a href="https://developer.android.com/training/data-storage/room">https://developer.android.com/training/data-storage/room</a><br />
<br />
<br />
<h3>
프로젝트 설정</h3>
<a href="https://developer.android.com/jetpack/androidx/releases/room#declaring_dependencies">https://developer.android.com/jetpack/androidx/releases/room#declaring_dependencies</a><br />
<br />
주의해야 할 것이 있는데 kotlin을 사용한다면 kapt를 사용해야 하고 kotlin-kapt 플러그인을 추가해야 함. 종속성 예시 아래에 별표로 알려주고 있는데 이를 미처 보지 못해서 실행 중 죽는 현상이 발생하여 원인 찾느라 고생함.<br />
<br />
build.gradle의 상단에<br />
<b>apply plugin: 'kotlin-kapt'</b><br />
<br />
를 명시하고 dependencies예제를 추가하되 annotationProcessor 대신 kapt를 사용함.<br />
<br />
def room_version = "2.2.3"<br />
implementation "androidx.room:room-runtime:$room_version"<br />
<b>kapt </b>"androidx.room:room-compiler:$room_version" <b>// For Kotlin use kapt instead of annotationProcessor</b><br />
<br />
kotlin에서 수정없이 사용하면 아래 에러 발생됨.<br />
<br />
<span style="font-size: x-small;"><i>E/AndroidRuntime: FATAL EXCEPTION: main</i></span><br />
<span style="font-size: x-small;"><i> Process: X.X.X, PID: 13160</i></span><br />
<span style="font-size: x-small;"><i> java.lang.RuntimeException: cannot find implementation for X.X.X.MyDatabase. MyDatabase_Impl does not exist</i></span><br />
<span style="font-size: x-small;"><i> at androidx.room.Room.getGeneratedImplementation(Room.java:94)</i></span><br />
<span style="font-size: x-small;"><i> at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:952)</i></span><br />
<br />
<br />
<h3>
구현</h3>
Room을 사용하여 로컬 데이터베이스에 데이터 저장<br />
<a href="https://developer.android.com/training/data-storage/room">https://developer.android.com/training/data-storage/room</a><br />
를 따라하면 쉽게 구현할 수 있음.<br />
<br />
주요 annotation은<br />
@Entity - DB에 저장할 data class/object<br />
@Dao - DB를 사용 시 필요한 interface 정의<br />
@Database - DB class, DB class 인스턴스화 시 DB가 생성되므로 아래 가이드 처럼 Singleton pattern class로 만들어야 함.<br />
<br />
<div style="box-sizing: inherit; color: #01579b; font-family: Roboto, "Noto Sans", "Noto Sans JP", "Noto Sans KR", "Noto Naskh Arabic", "Noto Sans Thai", "Noto Sans Hebrew", "Noto Sans Bengali", sans-serif; font-size: 14px; margin-bottom: 16px; padding: 0px;">
<i><b style="box-sizing: inherit;">참고: </b>앱이 단일 프로세스에서 실행되는 경우 <code dir="ltr" style="background: rgb(225, 245, 254); box-sizing: inherit; font-family: "Roboto Mono", monospace; font-size: 12.6px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; line-height: 1; padding: 0px; word-break: break-word;" translate="no">AppDatabase</code> 개체를 인스턴스화할 때 싱글톤 디자인 패턴을 따라야 합니다. 각 <a href="https://developer.android.com/reference/androidx/room/RoomDatabase" style="background: rgb(225, 245, 254); box-sizing: inherit; color: #01579b; outline: 0px;"><code dir="ltr" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; box-sizing: inherit; font-family: "Roboto Mono", monospace; font-size: 12.6px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; line-height: 1; padding: 0px; word-break: break-word;" translate="no">RoomDatabase</code></a> 인스턴스는 리소스를 상당히 많이 소비하며 단일 프로세스 내에서 여러 인스턴스에 액세스할 필요가 거의 없습니다.</i></div>
<br />
<h3>
비동기 호출</h3>
Room 사용 시 DB transaction이 꽤 시간이 소요 되므로<br />
UI thread에서 직접 호출할 수 없어 비동기적 방법을 사용해야 함.<br />
기존 Android에서는 AsyncTask 같은 것을 사용했었지만 Coroutine을 사용할 수 있음.<br />
<br />
<a href="https://kotlinlang.org/docs/reference/coroutines-overview.html">https://kotlinlang.org/docs/reference/coroutines-overview.html</a><br />
<a href="https://developer.android.com/topic/libraries/architecture/coroutines">https://developer.android.com/topic/libraries/architecture/coroutines</a><br />
<br />
<br />
아래 article도 참고할 만함.<br />
<a href="https://medium.com/androiddevelopers/room-coroutines-422b786dc4c5">https://medium.com/androiddevelopers/room-coroutines-422b786dc4c5</a><br />
<br />
<br />
<br />charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-83168452687284549992020-04-20T05:43:00.002-07:002020-04-20T05:43:25.451-07:00생체 인증을 위한 CheckboxPreference 만들기개인적으로 만드는 app에서 생체 인증을 사용하고자 하여 <div>
생체인증 enable/disable을 위한 CheckboxPreference로 옵션을 만들고 </div>
<div>
옵션을 변경할 때마다 생체 인증을 하도록 간략히 만들어 봄<div>
<br /></div>
<div>
사실 너무 간단한 내용이라 안드로이드 가이드만 봐도 충분하다. </div>
<div>
<a href="https://developer.android.com/training/sign-in/biometric-auth">https://developer.android.com/training/sign-in/biometric-auth</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
내가 구현하고자 했던 것은</div>
<div>
- 생체 인증을 enable/disable 하는 옵션</div>
<div>
- 생체 인증을 통해서만 옵션을 enable<->disable 할 수 있음</div>
<div>
- 생체 인증 실패 시에는 옵션 변경 없고 에러 발생 시 토스트 표시</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
안드로이드 생체인증 가이드를 기초하여 구현을 간략히 설명하면</div>
<div>
<br /></div>
<div>
1. 먼저 생체 인증을 위한 jetpack 라이브러리를 사용하고자 종속성을 추가한다.</div>
<div>
: 현재는 1.0.1 이다. 항상 Jetpack 라이브러리의 최신 버전을 확인해야 할 필요 있음.</div>
<div>
<pre class="none" dir="ltr" is-upgraded="" style="background: rgb(241, 243, 244); box-sizing: inherit; color: #37474f; font-family: "Roboto Mono", monospace; font-size: 14px; font-stretch: normal; font-variant-east-asian: normal; font-variant-numeric: normal; line-height: 20px; overflow-x: auto; padding: 24px; position: relative;" translate="no">dependencies {
implementation 'androidx.biometric:biometric:1.0.1'
}</pre>
</div>
<div>
<br /></div>
<div>
2. app 설정에서 CheckboxPreference 추가</div>
<div>
<br /></div>
<div>
<i><span style="font-size: x-small;"><checkboxpreference android:defaultvalue="false" android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" android:title="@string/settings_entry_enable_biometric_sign_in" app:iconspacereserved="false"></checkboxpreference><checkboxpreference android:defaultvalue="false" android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" android:title="@string/settings_entry_enable_biometric_sign_in" app:iconspacereserved="false"></checkboxpreference><checkboxpreference android:defaultvalue="false" android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" android:title="@string/settings_entry_enable_biometric_sign_in" app:iconspacereserved="false"></checkboxpreference><checkboxpreference android:defaultvalue="false" android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" android:title="@string/settings_entry_enable_biometric_sign_in" app:iconspacereserved="false"></checkboxpreference><checkboxpreference android:defaultvalue="false" android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" android:title="@string/settings_entry_enable_biometric_sign_in" app:iconspacereserved="false"></checkboxpreference><checkboxpreference android:defaultvalue="false" android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" android:title="@string/settings_entry_enable_biometric_sign_in" app:iconspacereserved="false"></checkboxpreference><CheckBoxPreference
app:iconSpaceReserved="false"
<br /> android:defaultValue="false" </span></i></div>
<div>
<i><span style="font-size: x-small;"> android:key="pref_enableBiometricSignIn" android:summary="@string/settings_summary_entry_enable_biometric_sign_in" </span></i></div>
<div>
<i><span style="font-size: x-small;"> android:title="@string/settings_entry_enable_biometric_sign_in" /></span></i></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
3. CheckboxPreference의 onPreferenceChangeListener에서 BiometricPrompt 표시</div>
<div>
<br /></div>
<div>
<i><span style="font-size: x-small;"><div>
val biometricCheckBox = findPreference("pref_enableBiometricSignIn") as CheckBoxPreference biometricCheckBox.onPreferenceChangeListener = OnPreferenceChangeListener { preference, newValue -></div>
<div>
<br /></div>
<div>
val promptInfo = BiometricPrompt.PromptInfo.Builder()</div>
<div>
.setTitle("Biometric login for app")</div>
<div>
.setSubtitle("Log in using your biometric credential")</div>
<div>
.setNegativeButtonText("Cancel")</div>
<div>
.build()</div>
<div>
val toBe = newValue as Boolean</div>
<div>
val biometricPrompt = BiometricPrompt(this, Executors.newSingleThreadExecutor(),</div>
<div>
object: BiometricPrompt.AuthenticationCallback() {</div>
<div>
</div>
<div>
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {</div>
<div>
super.onAuthenticationError(errorCode, errString) activity ? .runOnUiThread {</div>
<div>
Toast.makeText(activity ? .applicationContext, errString, Toast.LENGTH_SHORT).show()</div>
<div>
}</div>
<div>
}</div>
<div>
<br /></div>
<div>
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {</div>
<div>
super.onAuthenticationSucceeded(result) activity ? .runOnUiThread {</div>
<div>
(preference as CheckBoxPreference).isChecked = toBe</div>
<div>
}</div>
<div>
}</div>
<div>
}) </div>
<div>
<br /></div>
<div>
biometricPrompt.authenticate(promptInfo) </div>
<div>
false</div>
<div>
}</div>
</span></i></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
안드로이드 가이드 코드를 거의 그대로 사용하였고 원하는 기능을 위해 아래 사항을 살짝 수정함</div>
<div>
<br /></div>
<div>
- 생체 인증에 성공 시에만 옵션의 check status를 변경하고자 OnPreferenceChangeListener 구현</div>
<div>
: 생체 인증 시에만 check status를 변경하고자 OnPreferenceChangeListener의 리턴값을 false로 전달</div>
<div>
: 생체인증 성공시에만 isChecked 값을 OnPreferenceChangeListener의 argument인 newValue로 설정</div>
<div>
<br /></div>
<div>
- 사용자가 옵션을 변경할 때마다 생체 인증 창을 띄우기 위해 <span style="font-size: x-small; font-style: italic;">Executors.newSingleThreadExecutor()</span> 로 Executor 매번 생성</div>
<div>
: 솔직히 이게 맞는 것인지는 모르겠음 ㅜㅜ</div>
<div>
<br /></div>
<div>
- 생체 인증 중 지문이 틀릴 때마다 호출되는 <span style="background-color: #f1f3f4; color: #37474f; font-family: "Roboto Mono", monospace; font-size: 14px;">onAuthenticationFailed()</span> 를 override하지 않고 <span style="font-size: x-small; font-style: italic;">onAuthenticationError()</span> 만 override하여 사용자가 Cancel 하였을 때만 처리함 </div>
<div>
: 사용자가 생체 인증을 여러 번 틀려 block될 경우 BiometricPrompt에 안내가 표시되고 OnAuthenticationError()가 호출되기만 하고 사용자가 직접 cancel을 눌러야함.</div>
<div>
: block된 상황에서는 BiometricPrompt를 닫고 다시 옵션을 누르더라도 생체 인증창이 뜨지 않고 OnAuthenticationFailed()가 호출됨. </div>
<div>
<br /></div>
</div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-90007629897980918712020-04-15T22:51:00.000-07:002020-04-21T22:54:57.754-07:00OAuth 2.0 Authorization Framework<div>
<a href="https://tools.ietf.org/html/rfc6749">https://tools.ietf.org/html/rfc6749</a></div>
<div>
<a href="https://en.wikipedia.org/wiki/OAuth">https://en.wikipedia.org/wiki/OAuth</a></div>
<div>
<a href="https://oauth.net/2/">https://oauth.net/2/</a><br />
<a href="https://opentutorials.org/course/3405">https://opentutorials.org/course/3405</a><br />
<a href="http://www.yes24.com/Product/Goods/38100766?scode=032&OzSrank=3">http://www.yes24.com/Product/Goods/38100766?scode=032&OzSrank=3</a></div>
<div>
<a href="https://archive.org/details/mastering-oauth-2.0/mode/2up" target="_blank">https://archive.org/details/mastering-oauth-2.0/mode/2up</a><br />
<br />
<br />
상식선에서 대충 정리함.<br />
자세한 것들(header, field, flow 등)은 rfc 참고 필요<br />
<br />
<br />
<b><span style="font-size: large;">OAuth 2.0</span></b>은 Authorization framework로서<br />
HTTP 서비스에 대한 액세스 권한을 얻기 위해<br />
애플리케이션 승인 상호 작용을 정의하여<br />
타사 애플리케이션이 자체적으로 리소스와 HTTP 서비스에 접근할 수 있도록 함.<br />
<br />
<br />
<h3>
<b>먼저 인증(authentication) 인가(authorization)의 차이점</b></h3>
<div>
<br />
<a href="https://httpd.apache.org/docs/2.2/ko/howto/auth.html">https://httpd.apache.org/docs/2.2/ko/howto/auth.html</a></div>
<div>
<a href="https://hanee24.github.io/2018/04/21/authentication-authorization/">https://hanee24.github.io/2018/04/21/authentication-authorization/</a><br />
<br />
<blockquote class="tr_bq">
<i><span style="font-size: xx-small;">인증(authentication)은 자신이 누구라고 주장하는 사람을 확인하는 절차이다. 권한부여(authorization)는 가고 싶은 곳으로 가도록 혹은 원하는 정보를 얻도록 허용하는 과정이다.</span></i></blockquote>
</div>
</div>
<div>
<br />
<a href="https://www.oauth.com/oauth2-servers/openid-connect/authorization-vs-authentication/">https://www.oauth.com/oauth2-servers/openid-connect/authorization-vs-authentication/</a><br />
<a href="https://www.scottbrady91.com/OAuth/OAuth-is-Not-Authentication">https://www.scottbrady91.com/OAuth/OAuth-is-Not-Authentication</a><br />
<br />
OAuth는 authorization을 위한 framework이지 authentication을 고려한 것은 아님<br />
<br />
<br /></div>
<div>
<h3>
<b>OAuth 2.0의 Authorization Grant 종류</b></h3>
</div>
<div>
. Authorization code grant (인증 코드 기반 인가)</div>
<div>
. Implicit grant (암시적 인가)<br />
. Resource Owner Password Credentials Grant<br />
. Client Credentials Grant</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
클라이언트별 신뢰성에 따라 권고되는 인가 절차가 다름</div>
<div>
. 신뢰 클라이언트 => 인증 코드 기반 허가</div>
<div>
. 비 신뢰 클라이언트 => 암시적 허가</div>
<div>
<br />
각각의 인가 절차는 </div>
<div>
인가 코드 허가 절차<br />
- 서버 사이드 플로우이며</div>
<div>
- 복잡, 안전, 장기간</div>
<div>
암시적 허가 절차<br />
- 클라이언트 사이드 플로우</div>
<div>
- 단순, 보안성 낮음, 단기간</div>
<div>
<br />
<br /></div>
<div>
<h3>
<b>OAuth 2.0 기반 client 개발 절차</b></h3>
</div>
<div>
1. 클라이언트 앱 등록</div>
<div>
2. 액세스 토큰 얻기</div>
<div>
3. 액세스 토큰을 이용하여 보호된 리소스 접근</div>
<div>
4. 액세스 토큰 갱신</div>
<div>
<br /></div>
<div>
클라이언트 앱 등록 시 서비스로부터 다음 정보를 받게 됨</div>
<div>
. Client ID</div>
<div>
. Client secret</div>
<div>
. Redirection endpoint</div>
<div>
. Authorization endpoint</div>
<div>
. Token endpoint</div>
<div>
<br />
<br />
<br />
참고로 spec에서 말하는 용어들은 다음과 같다.<br />
<br />
<ul>
<li>Resource Owner : 사용자로서 리소스의 접근을 허가함.</li>
<li>Resource server : 리소스를 보호하는 서버로서 acces token을 통해 리소스 요청을 허가한다.</li>
<li>Authorization server : 사용자로의 인증, 인가를 통해 access token을 client에 발급하는 서버 </li>
<li>User-agent : 웹 브라우저</li>
</ul>
<div>
<br /></div>
<h3>
Implicit Grant, 암시적 허가 절차</h3>
<br /></div>
<div>
: <a href="https://tools.ietf.org/html/rfc6749#section-4.2">https://tools.ietf.org/html/rfc6749#section-4.2</a></div>
<div>
<br />
<ul>
<li>Implicit Grant 절차는 일반적인 client가 redirection URI를 사용하여 access token을 가져올 때 사용된다. </li>
<ul>
<li>client는 일반적으로 JavaScript를 이용하여 browser 내에서 동작한다.</li>
</ul>
<li>Redirection 기반이므로 client는 리소스를 제공자의 user-agent(웹브라우저)와 연동 가능해야 하고 authorization server로 전달되는 요청을 받을 수 있어야 한다.</li>
<li>Authorization 수행과 access token 획득을 위해 각각 요청하는 uthorization code grant 절차와 달리 본 절차는 client가 authorization 수행의 결과로 access token 획득하게 되고 access token은 redirection URI에 포함되어 전달되므로 노출될 수 있는 점을 고려해야 한다. </li>
</ul>
<br />
<br />
<pre class="newpage" style="break-before: page; font-size: 13.3333px;"> +----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
Note: The lines illustrating steps (A) and (B) are broken into two
parts as they pass through the user-agent.
Figure 4: Implicit Grant Flow</pre>
<pre class="newpage" style="break-before: page; font-size: 13.3333px;">
</pre>
<pre class="newpage" style="break-before: page; font-size: 13.3333px;">
</pre>
(A) 아래 client는 User-Agent(웹브라우저) 상에서 원하는 resource(정보, API) 접근 허가를 받고자 <br />identifier, requested scope, local state, redirection URI를 Authorization Server로 전달한다.<br />(B) 사용자가 User-Agent(웹브라우저)에서 인증(로그인 등) 하게 되면<br />(C) Authorization Server에서는 client에서 전달받은 redirection URI로 이동시킨다. </div>
<div>
이때 URI에 access token이 (parameter 형태로) 포함된다.<br />(D)(E)는 client가 web hosted 기반인 상황에 해당하는 절차이고<br />(F) User-Agent(웹브라우저)에서는 URI 이동을 감지하여 access token을 추출한다.<br />(G) Client에 access token을 전달한다.<br /><br /></div>
<div>
절차가 다르게 설명되어 있지만, Mastering OAuth2.0 책 삽화를 보면 이해하긴 쉬움.</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEFeCA5-yB9pDsuLR-3DcsxqJHIDgYtOryKfngcqVENOoNhlkYMeZTKXIbnQrna__Vz-0EofsA5LvmmII-d1hB-jfbuK6N4IzPOeuTUJZWTXfyKaCELG-4p4zQH-Fub0Gd-bWIi-_dMqN8/s1600/SmartSelect_20200413-205302_Chrome.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" class=" " data-original-height="1318" data-original-width="964" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEFeCA5-yB9pDsuLR-3DcsxqJHIDgYtOryKfngcqVENOoNhlkYMeZTKXIbnQrna__Vz-0EofsA5LvmmII-d1hB-jfbuK6N4IzPOeuTUJZWTXfyKaCELG-4p4zQH-Fub0Gd-bWIi-_dMqN8/s640/SmartSelect_20200413-205302_Chrome.jpg" title="" width="468" /></a></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br /><br /><br /><h3>
Authorization Code Grant, 인증 코드 기반 허가 플로우</h3>
<div>
: <a href="https://tools.ietf.org/html/rfc6749#section-4.1">https://tools.ietf.org/html/rfc6749#section-4.1</a><br />
<br />
<br />
<ul>
<li>Authorization Code Grant는 access token과 refresh token을 받기 위해 사용되며 신뢰할 수 있는 client를 대상으로 한다. </li>
<li>Redirection 기반이므로 client는 리소스를 제공자의 user-agent(웹브라우저)와 연동 가능해야 하고 authorization server로 전달되는 요청을 받을 수 있어야 한다.</li>
</ul>
<div>
<br /></div>
</div>
<div>
<pre class="newpage" style="break-before: page; font-size: 13.3333px;">
</pre>
<pre class="newpage" style="break-before: page; font-size: 13.3333px;"> +----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
Note: The lines illustrating steps (A), (B), and (C) are broken into
two parts as they pass through the user-agent.
Figure 3: Authorization Code Flow
</pre>
<pre class="newpage" style="break-before: page; font-size: 13.3333px;">
</pre>
<pre class="newpage" style="break-before: page; font-size: 13.3333px;"> </pre>
</div>
<div>
<br />
(A) 아래 client는 User-Agent(웹브라우저) 상에서 원하는 resource(정보, API) 접근 허가를 받고자 identifier, requested scope, local state, redirection URI를 Authorization Server로 전달한다.<br />(B) 사용자가 User-Agent(웹브라우저)에서 인증(로그인 등)을 하게 되면<br />(C) Authorization Server에서는 client에서 전달한 redirection URI로 이동시킨다.<br />
이때 URI에 authorization code가 (parameter 형태로) 포함된다.<br />
User-Agent(웹브라우저)에서는 redirection URI 변경을 감지하여 authorization code를 추출하여 Client에 전달한다.<br />
(D) Client는 access token을 발급받기 위해 전달받은 authorization code와 redirection URI을 Authorization Server로 전달한다.<br />
(E) Authorization Server는 client를 인증, authorization code 유효성 확인, redirection URI가 (C)에서 사용된 것과 동일한지를 확인한 뒤 access token를 (필요 시 refresh token도 함께) 전달한다.<br /><br /></div>
<div>
Mastering OAuth2.0 책 삽화를 참고</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXk043RCOUVhvcYIhAYi4Yn9hZurc_hgjqQfHbrmYamDHMj-h4Wyq_G-atespumQNUeCqhw5YXdiOhjJ7dAp-4rgvX8yTpy38znyX1YzksQG9olwmtZj4TO0wWXJtPa7i1-Lzy6XwporZr/s1600/pasted+image+0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" class=" " data-original-height="1600" data-original-width="1016" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXk043RCOUVhvcYIhAYi4Yn9hZurc_hgjqQfHbrmYamDHMj-h4Wyq_G-atespumQNUeCqhw5YXdiOhjJ7dAp-4rgvX8yTpy38znyX1YzksQG9olwmtZj4TO0wWXJtPa7i1-Lzy6XwporZr/s640/pasted+image+0.png" title="" width="406" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
<b>액세스토큰</b></div>
<div>
. 클라이언트가 보호된 리소스에 일시적으로 접근할 수 있도록 해주는 형식이 정해지지 않은 문자열.</div>
<div>
. 특정 범위의 권한으로 일정 기간 접근 할 수 있도록 해주며 서비스 제공자가 액세스 토큰의 권한 범위와 유효기간을 결정한다.</div>
<div>
. 서버로 전달은 주로 다음 방법을 통해 가능</div>
<div>
: 인가요청 헤더 필드에 담아서 전달</div>
<div>
: 인코딩된 폼의 파라미터로 전달</div>
<div>
: URI 질의 파라미터로 전달</div>
<div>
<br />
<br /></div>
<div>
<h3>
<b>액세스토큰 갱신(refresh)</b></h3>
</div>
<div>
. 리프레시 토큰 워크플로우</div>
<div>
. 인가 프로세스를 다시 시작하여 갱신 가능함.</div>
<div>
<br />
<pre class="newpage" style="break-before: page; font-size: 13.3333px;"><pre class="newpage" style="break-before: page; font-size: 13.3333px;"> +--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
Figure 2: Refreshing an Expired Access Token
</pre>
<div>
</div>
<div>
</div>
<div>
</div>
</pre>
</div>
<div>
화질이 좋진 않지만 액세스토큰 갱신 시 절차를 나타낸 diagram임<br />
위에서 말한 것과 같이 액세스토큰이 만료되는 경우 <br />
리프레시 토큰을 사용하여 갱신이 가능하지만 <br />
리프레시 토큰이 없다면 인가 절차를 다시 수행해야 함.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEWYiFNZ-k7hQRnJPToUbepbyJu8d8fFgEw9MzFPFTIIe9eXzRGqv9626av8m677QbeFjuPNBHaAse0QTFLoJ-WFcwYTiY7yCvjiNjxfXK6DAtutpuKpDFz9DyHrXX_hMuJY7aGix7E2cZ/s1600/images.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" class=" " data-original-height="209" data-original-width="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEWYiFNZ-k7hQRnJPToUbepbyJu8d8fFgEw9MzFPFTIIe9eXzRGqv9626av8m677QbeFjuPNBHaAse0QTFLoJ-WFcwYTiY7yCvjiNjxfXK6DAtutpuKpDFz9DyHrXX_hMuJY7aGix7E2cZ/s1600/images.png" title="" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
<b>보안을 위해 고려해야 하는 사항들은 다음과 같다. </b><br />
<b>(</b><b>Mastering OAuth2.0 책 내용)</b></div>
<div>
<br />
<br />
<ul>
<li>TLS를 사용하라</li>
<li>최소한의 범위만을 요청하라</li>
<li>암시적 그랜트 플로우를 사용할 때는 읽기 전용 권한만을 요청하라.</li>
<li>사용자의 손이 미치지 않는 곳에 자격증명과 토큰을 보관하라 </li>
<li>가능하면 항상 인가 코드 그랜트 플로우를 사용하라</li>
<li>가능하면 항상 리프레시 토큰을 사용하라</li>
<li>내장 브라우저 대신 네이티브 브라우저를 사용하라</li>
<li>리다이렉션 엔드포인트에서 서드파티 스크림트를 사용하지 말라</li>
<li>클라이언트 자격증명을 바꿔서 사용하라</li>
</ul>
</div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-47232476552255910652020-03-18T05:41:00.000-07:002020-05-07T05:41:57.199-07:00나는 LINE 개발자입니다 : 라인의 개발 고수 12인의 도전과 기회, 성장의 개발 라이프<div>나는 LINE 개발자입니다 : 라인의 개발 고수 12인의 도전과 기회, 성장의 개발 라이프</div><div>강윤신,김영환,김재석,김정엽,김택주 저 외 7명 | 한빛미디어</div><div><a href="http://m.yes24.com/goods/detail/78226025" target="_blank">http://m.yes24.com/goods/detail/78226025</a><br></div><div><br></div><div><br><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gaZaUa38SR46rI9DTf0KuKwApkPQhQaeftoonVhYqodAMddhyphenhyphengXkmpB2Sz47lmcSCWYy9CcQTf-p2NXBSUZ6HYA74edi3nRxpaMvnCFyaNIytGIRLb78zmBP6sPZvD8GW2cfiXC2HeMR/s1600/unnamed+%25281%2529.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gaZaUa38SR46rI9DTf0KuKwApkPQhQaeftoonVhYqodAMddhyphenhyphengXkmpB2Sz47lmcSCWYy9CcQTf-p2NXBSUZ6HYA74edi3nRxpaMvnCFyaNIytGIRLb78zmBP6sPZvD8GW2cfiXC2HeMR/s1600/unnamed+%25281%2529.jpg" border="0" data-original-width="352" data-original-height="512" width="220" height="320"></a></div><br></div><div><br></div><div>궁금해서 읽어 봤는데 결국 LINE 홍보 도서 같다.</div><div>참고로 머리말에서 이렇게 언급하고 있다. </div><div>"이 책은 흔한 자기개발서가 아니다. 기술 서적은 더더욱 아니다. IT기업에 합격이 잘되기 위한 절대 무공비급이 들어 있는 것도 아니다</div><div>...</div><div>라인에서 동료들과 함께 개발자로서 또 한던계 성장하고 도전하면서 느끼도 배운 경험담을 통해 개발자를 꿈꾸는 이 땅의 청년들에게 비전을 보여주고 꿈과 희망을 전달하고 싶었다."</div><div><br></div><div>저자의 경력과 분야가 다양하여 개발자를 꿈꾸거나 개발자인 사람들이 읽고 여러 분야를 간접 체험할 수 있을 것으로 생각된다.</div><div><br></div><div>하지만 읽고 나면 라인 뽐뿌가 상당하니 조심해야 할 듯 ㅎ</div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-44270380356830555092020-01-22T15:55:00.000-08:002020-04-02T16:09:03.214-07:00Galaxy Watch용 Tizen xamarin app에서 Entry에 의한 화면 깨짐 발생 시Galaxy Watch app을 Xamarin.forms를 이용해서 C#으로 만들 수 있음.<br />
<a href="https://samsung.github.io/Tizen.CircularUI/guide/Quickstart.html">https://samsung.github.io/Tizen.CircularUI/guide/Quickstart.html</a><br />
기존에는 어려운 EFL 기반 app이나 web app을 만들어야 했는데 이제는 C#으로도 개발할 수 있음.<br />
<br />
암튼 Watch 용 app을 하나 만들어 보는 중에<br />
입력을 위한 Page가 필요하여 Entry를 추가하게 되었음.<br />
<br />
하지만 페이지에서 Entry를 선택하면 Virtual Keyboard가 떠서<br />
Page layout 밀려 올라가 이상하게 보이는 현상이 발생했다.<br />
<br />
관련하여 다른 옵션이 없는지 확인 중 Tizen에서 제공하는 CircularUI가 있고 <br />
그 중에 PopupEntry를 제공하는 것을 확인하였음.<br />
<br />
<a href="https://samsung.github.io/Tizen.CircularUI/guide/PopupEntry.html">https://samsung.github.io/Tizen.CircularUI/guide/PopupEntry.html</a><br />
<br />
Popup Entry는 일반적으로 Galaxy Watch app에서 사용되는<br />
전체화면을 가리는 popup으로 입력창과 키보드가 떠서<br />
기존 Page layout에는 영향을 주지 않고 입력할 수 있게 해준다.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD5LIKcnIX_P1MrdyNUiZBZqZjsMWVLQHyQDfGZKh_Eh9mtlR3jC1_3XWE0r8SWVd2UeQ8VN1pnSL5QjArR0AqgRoSAg6lZOmkPXAL1Ty-5gkR1WpHLa3UoHDueeRo2dJS6MzH23BlwlMn/s1600/SmartSelect_20200403-080722_Chrome.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" class=" " data-original-height="1049" data-original-width="978" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD5LIKcnIX_P1MrdyNUiZBZqZjsMWVLQHyQDfGZKh_Eh9mtlR3jC1_3XWE0r8SWVd2UeQ8VN1pnSL5QjArR0AqgRoSAg6lZOmkPXAL1Ty-5gkR1WpHLa3UoHDueeRo2dJS6MzH23BlwlMn/s400/SmartSelect_20200403-080722_Chrome.jpg" title="" width="373" /></a></div>
<br />
<br />
<br />
참고로 안드로이드에서는 다음과 같이 처리하고 있음.<br />
<a href="https://www.milestre.nl/blog/blogitem/milestre-blog/2019/01/08/to-avoid-soft-keyboard-overlap">https://www.milestre.nl/blog/blogitem/milestre-blog/2019/01/08/to-avoid-soft-keyboard-overlap</a><br />
<br />
<i><span style="font-size: x-small;">//To avoid soft keyboard statusbar overlap Xamarin.Forms.Application.Current.On<xamarin .forms.platformconfiguration.android="">().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);</xamarin></span></i><br />
<br />charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-31837336746551766862019-10-31T04:11:00.003-07:002019-10-31T04:11:31.714-07:00DEVIEW 2019 Day2 참가 세션 메모<div>
세션에 참가해서 필요한 내용이나 기억에 남길 것을 메모함. 자세한 내용은 발표자료 참고.</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiExafD5CtoyrFGehmE0HMYLiF2BQStGOnrcRAfToFhGJq3n8_R5U-R3VOniQGQsH7Xc2Ers4eN-pvVv382SoIaA2K-HM3lnS5LJo9GztAPzSGBK5coHiohbpfekbxHPW9LWFP6d5zFwok/s1600/20191029_100017.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiExafD5CtoyrFGehmE0HMYLiF2BQStGOnrcRAfToFhGJq3n8_R5U-R3VOniQGQsH7Xc2Ers4eN-pvVv382SoIaA2K-HM3lnS5LJo9GztAPzSGBK5coHiohbpfekbxHPW9LWFP6d5zFwok/s640/20191029_100017.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[Multi-Tenancy Kubernetes on Bare-Metal Servers (네이버 컨테이너 클러스터)]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/275">https://deview.kr/2019/schedule/275</a></div>
<div>
<br />
이팀은<br />
. Container oriented : 베어메탈, 컨테이너 오케스트레이션</div>
<div>
. Cost efficient : 범용서버 직접 구축</div>
<div>
. Help containerize : 컨테이너 클러스트 + 레지스트리, 모니터/로깅, 교육,가이드 등 컨테이너화를 촉진하는 활동</div>
<div>
<br /></div>
<div>
효율적인 컨테이너 적용하려고 노력함 > Multi-Tenancy Kubernetes 로 불림</div>
<div>
= 하나의 Kubernetes를 namespace로 나눠서 제공하는 것</div>
<div>
<br /></div>
<div>
Pros</div>
<div>
. 모든 사용자가 Kubernetes자체 서버를 보유할 필요 없음<br />
. 모든 사용자를 의한 여유 리소스를 보유할 필요 없음.<br />
. 모든 사용자가 직접 Kubernetes를 운영할 필요 없음</div>
<div>
Cons</div>
<div>
. 신뢰성 있는 유저 필요<br />
. 사용자가 Kubernetes의 모든 기능을 사용 할 수 없음<br />
. Kubernetes가 매우 커지고 사용자도 많아서 운영하기 힘듬</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU4jybMp_tUsm-XquXFt8WpCLwfiEf_hTdGlWkpmOHiX4ZIeoi_ogHhsaBYKK_3eHt3stHNMDiuaN68aiH43vbUIcqghSoRj0qtRzMgOsqudgVRQal3aly66_tyu6gTZVMERkPdoxFNTAN/s1600/20191029_100855.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU4jybMp_tUsm-XquXFt8WpCLwfiEf_hTdGlWkpmOHiX4ZIeoi_ogHhsaBYKK_3eHt3stHNMDiuaN68aiH43vbUIcqghSoRj0qtRzMgOsqudgVRQal3aly66_tyu6gTZVMERkPdoxFNTAN/s640/20191029_100855.jpg" width="640" /></a></div>
<br /></div>
<div>
현재 네이버</div>
<div>
12+ 클러스터, 300+ 네임스페이스, 1000+ 유저</div>
<div>
가장 큰 싱글 클러스터에 5000+ 팟 10000+ 컨테이너</div>
<div>
<br /></div>
<div>
2019 목표 => Elastic, efficient</div>
<div>
<br /></div>
<div>
Elastic한 서빙</div>
<div>
.대규모, 실시간, 신뢰성</div>
<div>
<br /></div>
<div>
Efficient한 리소스 활용</div>
<div>
.리소스 여구량, 시간대별 사용령이 모두 다름</div>
<div>
.여유 리소스 최소화</div>
<div>
.서버 대수 최소화 </div>
<div>
<br /></div>
<div>
로드밸러스 지표는 전체의 5% 수준 </div>
<div>
> 800+ 200mac 32kcps 3G througbput</div>
<div>
<br /></div>
<div>
Kubernetes</div>
<div>
대규모 클러스터 (20 node vs 500 node)</div>
<div>
. 다수 클러스터 노드 관리, 관리서버(ETCD, api server) 과부하, 복잡해지는 관리시스템</div>
<div>
<br /></div>
<div>
사용 제한 </div>
<div>
. 클러스터 영향을 주는 API 제한, 클러스터 전체에 적용되는 권한 제한 > 오픈소스 활용 걸림돌(노드/클러스터 분리, 전체 적용)</div>
<div>
<br /></div>
<div>
다양한 요구사항을 Affinity/Anti affinity 로 해결</div>
<div>
. 노드 분리(private node 등), 리소스 장애 예방(리소스 부족 노드에 anti affinity 적용)</div>
<div>
<br /></div>
<div>
Runtime의 리소스 제한</div>
<div>
. LimitRange 정책으로 container/pod의 리소스를 제한 (cpu 0.1 min 4 8 max), request는 limit 비율에 맞춰</div>
<div>
<br /></div>
<div>
Namespace Quota로 사용자별 허용 리소스 제어</div>
<div>
<br /></div>
<div>
Rescheduling</div>
<div>
.long run pod이 많은 노드의 리소스 부족</div>
<div>
.사용자가 request/limit을 잘 설정 안함</div>
<div>
.스케줄러가 똑똑하지 않은 것 같음</div>
<div>
> 심할경우 강제로 pod?를 죽임</div>
<div>
<br /></div>
<div>
자동제공 모니터링</div>
<div>
.Prometheus/grafana provisioning 잘 정리된 텝플릿 제공</div>
<div>
.kube event를 사용자가ㅜ 인 할 수 있도록</div>
<div>
<br /></div>
<div>
내년에</div>
<div>
Network,resouce, runtime에 대한 isolation</div>
<div>
Kubernetes Reliable Engineering + SRE</div>
<div>
보다 많은 Cloud Native 서비스로 네이버의 경쟁력을 향상하도록</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0OpjXmNsl2MMwN7BxzCRSx8cgt9bpf30lqNU69lfVGIq56zOU6TFvn7FZ1S0z0EkqS1qK8q1H2M-FJUdI4Q3AsLYj2t4DfV2D0DAhHrpdG4xWMeah6cYA2_vBL7pTSvY7WwdqdN6ZFsl_/s1600/20191029_110021.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0OpjXmNsl2MMwN7BxzCRSx8cgt9bpf30lqNU69lfVGIq56zOU6TFvn7FZ1S0z0EkqS1qK8q1H2M-FJUdI4Q3AsLYj2t4DfV2D0DAhHrpdG4xWMeah6cYA2_vBL7pTSvY7WwdqdN6ZFsl_/s640/20191029_110021.jpg" width="640" /></a></div>
</div>
<div>
<br /></div>
<div>
<b>[안드로이드 앱의 다중 웹뷰 환경에서 성능 병목 진단 및 최적화 사례]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/287">https://deview.kr/2019/schedule/287</a></div>
<div>
<br /></div>
<div>
웹브라우저 엔진 vs 시스템 엔진</div>
<div>
. 웹뷰 파편화 vs 유지보수 비용</div>
<div>
. 웹뷰를 내장 시 크기 증가 vs 플랫폼은 버전별 피쳐 다름</div>
<div>
<br /></div>
<div>
XWhale </div>
<div>
. Crosswalks 계승</div>
<div>
. 시스템 웹뷰 대체</div>
<div>
. 네이버앱과 네이버 카페</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
사용성개선을 위한 다중 웹뷰 활용 </div>
<div>
<br /></div>
<div>
<div>
. 앱 초기화 시 복수의 웹뷰 사전 생성</div>
<div>
=> 백그라운드 로딩 및 렌더링 수행으로 반응성 개선 예상</div>
</div>
<div>
<br /></div>
<div>
다중 웹뷰 생성에 따른 부담</div>
<div>
. 브라우저 엔진 초기화</div>
<div>
. Renderer 프로세스 생성 </div>
<div>
. 웹뷰 생성 </div>
<div>
. 웹페이지 로딩 </div>
<div>
<br /></div>
<div>
웹뷰 생성 측면</div>
<div>
.웹뷰 생성 지연 이슈</div>
<div>
.웹페이지 로딩 지연 이슈 (IPC로 인해 navigation이 시작되기전 지연)</div>
<div>
>비동기 웹뷰 초기화 400ms, 백그라운드 웹뷰 초기화 지연 400ms</div>
<div>
<br /></div>
<div>
웹페이지 로딩 성능 측면</div>
<div>
각 주제판에서 동일 css 파싱 시 시간 소모</div>
<div>
. Loading은 caching되지만 parsing은 caching이 안됨</div>
<div>
비용이 높은 js 문제</div>
<div>
. Layout의 큰 변화를 야기하는 js</div>
<div>
. DOM 전반에 대한 전면적인 변경</div>
<div>
> rendering reschdule는 의미 없음 </div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmXHQB-i8-9J42A5kUczwfFIt-FUdEkuBms6fcAGFXotx03ugKadmvTw3IKx1RTCnZXVEkNzLRjKN2S4jgt3yI9gCngG7f3iD8lrLmIPiUM9DiykCT21hlNxV2R_OhgV9DeE5PLbKMypZE/s1600/20191029_111858.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmXHQB-i8-9J42A5kUczwfFIt-FUdEkuBms6fcAGFXotx03ugKadmvTw3IKx1RTCnZXVEkNzLRjKN2S4jgt3yI9gCngG7f3iD8lrLmIPiUM9DiykCT21hlNxV2R_OhgV9DeE5PLbKMypZE/s640/20191029_111858.jpg" width="640" /></a></div>
<br /></div>
<div>
성능지표?</div>
<div>
. W3C navigation timing APi5 </div>
<div>
. RAIL 성능 모델 </div>
<div>
: Response, Animation, Idle, Load</div>
<div>
. First meaningfulpaint </div>
<div>
: First meaningful paint : 페이지 layout이 급격히 변하는 순간</div>
<div>
. Time to interactive </div>
<div>
. User metrics histogram </div>
<div>
: chrome 브라우저에 실행정보가 누적된 in-memory DB, cache hit ratio 확인 가능</div>
<div>
<br /></div>
<div>
HTTP cache의 맹점</div>
<div>
이미지 로딩 부하</div>
<div>
<br /></div>
<div>
성능 개선 방안</div>
<div>
. Background 웹뷰 생성 지연 </div>
<div>
> 다른 리소스로 인해 종료 시간은 동일</div>
<div>
. 브라우저엔진 비동기 초기화</div>
<div>
> thread 생성 overhead, callback의존성으로 효과 미비</div>
<div>
. Priviligded HTTP cache 구현 </div>
<div>
> 지정된 URL 패턴, 지정된 referer, 지정된 resource type에 대해서 보존 기간 보장</div>
<div>
> image cache hit ratio 14%, paint 30-40m 향상</div>
<div>
> lower tier에서 80-120ms 개선 효과</div>
<div>
. Cross Webview CSS cache 구현</div>
<div>
> Render 프로세스가 모든 웹뷰 접근(global cache)</div>
<div>
> css rule set은 웹페이지의 라이프사이클과 맞춤</div>
<div>
> 466ms의 CSS parsing이 한번만 발생</div>
<div>
. Proxy기반 이미지 최적화</div>
<div>
> 디바이스 디스플레이 파편화에 대응이 어려움</div>
<div>
> 실제로 화면에서 보여주는 사이즈가 그림 사이느보다 커서 그닥..</div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMX_P4fJVqAxYW_WvaUC4gLOkRg93NxKEsFiN5Zh4ayet9aQy4MCGcV8LaMbR-TFAlbXvd_pQofh33qgzWV_QZb8SBAtXlaRoiJwptwyyWOg8T-7QbKbh7357Adg3QLbNZJ5drx9QOoC8F/s1600/20191029_120018.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMX_P4fJVqAxYW_WvaUC4gLOkRg93NxKEsFiN5Zh4ayet9aQy4MCGcV8LaMbR-TFAlbXvd_pQofh33qgzWV_QZb8SBAtXlaRoiJwptwyyWOg8T-7QbKbh7357Adg3QLbNZJ5drx9QOoC8F/s640/20191029_120018.jpg" width="640" /></a></div>
</div>
<div>
<br /></div>
<div>
<b>[앱 패러다임 변화 어떻게 적응할 것인가? (모듈 중심의 안드로이드 앱 설계)]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/304">https://deview.kr/2019/schedule/304</a></div>
<div>
<br /></div>
<div>
뭐가 변했는가?</div>
<div>
Hardware(멀티코어, 드양한 디스플레이) </div>
<div>
Platform </div>
<div>
. Dalvik->JIT/ART </div>
<div>
. APP Bundle(Dynamic Feature & Delivery) </div>
<div>
Language (FunctionalProgramming, kotlin)</div>
<div>
다양한 프레임워크 </div>
<div>
. JetPack </div>
<div>
. RxJava </div>
<div>
. Lottie </div>
<div>
. Retrofit </div>
<div>
. Glide, Picasso, OkHttp </div>
<div>
<br /></div>
<div>
좋은 앱은? </div>
<div>
. Multi-Featured </div>
<div>
. Multi-Media </div>
<div>
. Multi-CORE </div>
<div>
. Big-Sized </div>
<div>
. Multi-Module </div>
<div>
에서 효율적 + 빠른 개발과 유지 보수 </div>
<div>
<br /></div>
<div>
함수형 프로그래밍 - 간결한 코딩, 이벤트 처리 효율성</div>
<div>
<br /></div>
<div>
안드로이드는 Activity가 메인이자 하나의 앱 단위가 될 수도 있음. </div>
<div>
So library를 로드하면 프로세스를 다시 띄워 죽이지 않는 한 살아 있음</div>
<div>
멀티프로세스 지원 필요</div>
<div>
<br /></div>
<div>
아키텍쳐 기반의 접근</div>
<div>
Language Tookit </div>
<div>
. Kotlin Tookit </div>
<div>
View-Data 패턴 </div>
<div>
. MV. MVC. MVP. MVVM </div>
<div>
State Model. Finite State Machine </div>
<div>
. State Model- 간단한 이벤트로 상태관리 (디바이스) </div>
<div>
. FSM - 이벤트에 따른 상태변화와 동작 구조(프로토콜, 앱상태) </div>
<div>
Media Processing </div>
<div>
. Piped Stream Model </div>
<div>
. Multiplexed Event Queue Model </div>
<div>
모듈화 </div>
<div>
. Layed Project</div>
<div>
. Dynamic Feature Module</div>
<div>
<br /></div>
<div>
어떤 것을 어떻게 적용할까?</div>
<div>
.Kotlin toolkit </div>
<div>
.이벤트 라우팅 필요</div>
<div>
.View data model</div>
<div>
.Network model</div>
<div>
.Multimedia model</div>
<div>
: MQ(센서), Produce-consumer(미디어생성 소비),pipes&filters(실시간 미디어 생성 소비)</div>
<div>
.대용량앱 모듈 구조</div>
<div>
: 안드로이드 제공 기술을 사용 가능하나 결국 프로젝트, 모듈, 리소스, 코드를 컴포넌트로 분리하는게 필요함</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5d1Q0Xw2wC88d8ERvdaN9pZxMrK28olHksC0zVfW80zU2isw6qwNlRe0BXuGLjhu105tFLw_l_fCid9ojjyKdMTJya2C8DGWwx24DZy8KfIzHfF9SPZctkoeJGjqJSayQmviXt2dfOI-e/s1600/20191029_124446.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5d1Q0Xw2wC88d8ERvdaN9pZxMrK28olHksC0zVfW80zU2isw6qwNlRe0BXuGLjhu105tFLw_l_fCid9ojjyKdMTJya2C8DGWwx24DZy8KfIzHfF9SPZctkoeJGjqJSayQmviXt2dfOI-e/s640/20191029_124446.jpg" width="640" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3NWNTpzClDUTYX8yhgjyXofO1PhWcvSVpghWHwEi3YodlSykOqc_MYSXgsnOxjLoAY1VmNNtMdY6qoGxARqYQYdnqLNWbfm4GChN-MoEt3UCaUlPTpY54saren7KmIXbyB6WpNI7gvy04/s1600/20191029_135934.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" class=" imageResizeTarget" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3NWNTpzClDUTYX8yhgjyXofO1PhWcvSVpghWHwEi3YodlSykOqc_MYSXgsnOxjLoAY1VmNNtMdY6qoGxARqYQYdnqLNWbfm4GChN-MoEt3UCaUlPTpY54saren7KmIXbyB6WpNI7gvy04/s640/20191029_135934.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[React, Angular, Vue를 한 번에 지원하기 위한 설계 (Cross Framework Component)]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/289">https://deview.kr/2019/schedule/289</a></div>
<div>
<br /></div>
<div>
Cross Framework Component(CFC)</div>
<div>
> 하나의 공통 모듈 기반으로 다양한 프레임워크를 지원하기 위해 효과적인 구조를 가진 컴포넌트</div>
<div>
<br /></div>
<div>
Egjs의 바닐라 컴포넌트를 제공하여 다양한 기능을 사용할 수 있게 하였지만 프레임워크에서 사용 시 문제 발생</div>
<div>
: 바닐라 컴포넌트가 각 프레임워크에서 동작이 다르거나 프레임워크에서 필요한 기능을 제공하지 않을 수 있음.</div>
<div>
<br /></div>
<div>
프레임워크를 래핑하거나 수정한다면 동작 이상 중복 코드의 문제다 있음 > DOM 조작</div>
<div>
<br /></div>
<div>
DOM diff</div>
<div>
.?</div>
<div>
<br /></div>
<div>
CFC 원리</div>
<div>
. 컴퍼넌트에서는 data를 삭제해야하지만 프레임워크에서 dom을 삭제하므로 데이터만 삭제 필요.</div>
<div>
. 데이터 확인, 동기화?를 위한 listdiffer 를 만듬</div>
<div>
. 프레임워크에서는 dom을 삭제 후 listdiffer로 동기화(삭제 > 유지 > 추가)</div>
<div>
<br /></div>
<div>
*자세한 내용은 발표자료*</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<a href="https://naver.github.io/egjs/">https://naver.github.io/egjs/</a></div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghD7vU6JddJFuWwQlpAiQL40amkWIU1Im_By_1_0rQXcfiv7OGBrHrB_iynB-gkwp9jZRJqhAPQJ-uVv9i-hD9x9yzr4rXq1pMtgxJRXoTo0u2tgbF62bSuOsgSH4eAKsS9hg4UnzAMYVr/s1600/20191029_145133.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghD7vU6JddJFuWwQlpAiQL40amkWIU1Im_By_1_0rQXcfiv7OGBrHrB_iynB-gkwp9jZRJqhAPQJ-uVv9i-hD9x9yzr4rXq1pMtgxJRXoTo0u2tgbF62bSuOsgSH4eAKsS9hg4UnzAMYVr/s640/20191029_145133.jpg" width="640" /></a></div>
</div>
<div>
<br /></div>
<div>
<b>[2019년 FE 프레임워크를 배우는 기분(FE 인싸들이라면 알고 있어야 하는 프레임워크 기술들)]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/320">https://deview.kr/2019/schedule/320</a></div>
<div>
<br /></div>
<div>
발표자료를 읽어보자.</div>
<div>
발표자료가 정말 인싸의 자료답다~!</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzKOCLGGh7IzyeK0WNL1V4lDMkqEOUh8AQ12u2ORUtytkSsQ-4q1-54B9RFOeCQwwhSxyPIHqHAE_zz8W80G-Ys1PMktCeRBL-tgXEo-Dvx4hQJkS7syKesnEV5rbng6niud0LBI9iUDZg/s1600/Screenshot_20191029-203716_Drive.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1080" data-original-width="1593" height="432" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzKOCLGGh7IzyeK0WNL1V4lDMkqEOUh8AQ12u2ORUtytkSsQ-4q1-54B9RFOeCQwwhSxyPIHqHAE_zz8W80G-Ys1PMktCeRBL-tgXEo-Dvx4hQJkS7syKesnEV5rbng6niud0LBI9iUDZg/s640/Screenshot_20191029-203716_Drive.jpg" width="640" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm9UsB08sa9frcckT8SrcfJaH-1mYS0vhjhwfLrJ23TuuQYwDRjyaoK5R5tK0ggBeWkZO164JU-JN3JcPdPxgx75SPX6A0LL_X-yV9ZXfP1Co_L9_CTnpXRm8dmLAplMUXJkzil0PkjuGK/s1600/20191029_155959.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm9UsB08sa9frcckT8SrcfJaH-1mYS0vhjhwfLrJ23TuuQYwDRjyaoK5R5tK0ggBeWkZO164JU-JN3JcPdPxgx75SPX6A0LL_X-yV9ZXfP1Co_L9_CTnpXRm8dmLAplMUXJkzil0PkjuGK/s640/20191029_155959.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[Armeria: 어디서나 잘 어울리는 마이크로서비스 프레임워크]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/283">https://deview.kr/2019/schedule/283</a></div>
<div>
<br /></div>
<div>
<a href="https://github.com/line/armeria">https://github.com/line/armeria</a></div>
<div>
<br /></div>
<div>
마이크로서비스에 대한 간략한 설명과<br />
만드신 프레임워크의 장점에 대해서 소개하심<br />
함께 slack이나 nhn, kakao에서 적용한 사례를 말씀하심.<br />
<br /></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-13958199161378408862019-10-29T08:04:00.001-07:002019-10-29T08:04:57.102-07:00DEVIEW 2019 Day1 참가 세션 메모<div>
세션에 참가해서 필요한 내용이나 기억에 남길 것을 메모함. 자세한 내용은 발표자료 참고.</div>
<div>
솔직히 ML, AI는 뭔소린지 모르겠음.<br />
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQmT82FQm_PNWCsiIsEeDLSv3Xuidyvs9cRpKo54h7qFswo1W5BMiJVSVlpOjqRxT5NOUeT6-9tXze08ru-rt5RXQbP9nY-3z4p2a8IH6DjtdqzXKZpqPqjoRpW-RouxZgN65nckBu_IOZ/s1600/20191028_113021.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQmT82FQm_PNWCsiIsEeDLSv3Xuidyvs9cRpKo54h7qFswo1W5BMiJVSVlpOjqRxT5NOUeT6-9tXze08ru-rt5RXQbP9nY-3z4p2a8IH6DjtdqzXKZpqPqjoRpW-RouxZgN65nckBu_IOZ/s640/20191028_113021.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[외산 클라우드 없이 AI 플랫폼 제공하기: features, training, serving, and AI Suite]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/303">https://deview.kr/2019/schedule/303</a></div>
<div>
<br /></div>
<div>
자체 AI 플랫폼 이유</div>
<div>
.security - 국내 데이터는 국내에서, 지리, 정부 승인 등</div>
<div>
.cost </div>
<div>
.demand</div>
<div>
<br /></div>
<div>
네이버는 사용하던 AI 플랫폼이 있었음</div>
<div>
이를 엮어서 > AI Suite : End-to-End AI platform</div>
<div>
<br /></div>
<div>
머신러닝을 위해서</div>
<div>
데이터 처리 ㅡ 모델 학습 ㅡ 서빙이 필요함.</div>
<div>
실제 개발에서는 </div>
<div>
=> 데이터 처리가 오래 걸림, 자동화 고려 필요</div>
<div>
<br /></div>
<div>
AI Feature 안에서</div>
<div>
. Dump : 데이터를 가져오고<br />
. Analyze : 가시화를 통한 인사이트<br />
. Batch : 데이터를 선별하여 feature vector생성</div>
<div>
<br /></div>
<div>
Facets</div>
<div>
단점 </div>
<div>
. 모든 데이터 클라이언트에서 돌리므로 성능 이슈 > 샘플링을 통해서 통계를 보고 인사이트를 얻음</div>
<div>
. HDFS라 전체를 다 읽어야 샘플링 가능 > 일부를 읽어서 전체를 예상하고 estimation 하여 샘플링</div>
<div>
<br /></div>
<div>
모델연구시</div>
<div>
. 최대 GPU자원 사용</div>
<div>
. 동시 사용하여 성능 좋은 모델 선정</div>
<div>
. 데이터 고정으로 캐싱하면 이득</div>
<div>
<br /></div>
<div>
하지만 제품화 시</div>
<div>
. 최소한의 자원 사용 (비용문제 이유)</div>
<div>
. 배포전 이전 모델의과 품질을 검증 필요</div>
<div>
. 새로운 데이터로 캐싱 의미 없음</div>
<div>
<br /></div>
<div>
서빙 = APS 서빙 + 모델 서빙</div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4c6bibErHlA0IZfB4emw5W5KTsQA224V80SpY2QxTsynZb0hzHuRWfpeynkXnfKtZy1AShAsEJYWASZZgDCDKlBjCeYhbgsjY6N5448T7r1PodVBC31Wlz2h98FzP-wVfpVrC6jwFGbYB/s1600/20191028_131530.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4c6bibErHlA0IZfB4emw5W5KTsQA224V80SpY2QxTsynZb0hzHuRWfpeynkXnfKtZy1AShAsEJYWASZZgDCDKlBjCeYhbgsjY6N5448T7r1PodVBC31Wlz2h98FzP-wVfpVrC6jwFGbYB/s640/20191028_131530.jpg" width="640" /></a></div>
<br />
<br /></div>
<div>
<b>[Papago: Engineering BERT into NMT]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/296">https://deview.kr/2019/schedule/296</a></div>
<div>
<br /></div>
<div>
몇가지 적긴 했는데 그냥 발표자료를 참고하여 논문을 찾아 읽어야 할 듯</div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQyuQezXmR5DaD2678YxmLaMkW86mJKnfP6u-vxIKcr7WgDIT7gh6R2ERq4urvXcrbGq-SMwT5fVf4dJIAa6DG40Phf5trmGMu_EfUUEiXJBcNsjltgF5j_QVBhTZ8xosko58iEN4-Bqtk/s1600/20191028_141537.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQyuQezXmR5DaD2678YxmLaMkW86mJKnfP6u-vxIKcr7WgDIT7gh6R2ERq4urvXcrbGq-SMwT5fVf4dJIAa6DG40Phf5trmGMu_EfUUEiXJBcNsjltgF5j_QVBhTZ8xosko58iEN4-Bqtk/s640/20191028_141537.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[챗봇 1만 개의 모델 서빙하기: AI 서비스 어디까지 해봤니]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/310">https://deview.kr/2019/schedule/310</a></div>
<div>
<br /></div>
<div>
중요한 건 모델의 규모와 서비스 형태 </div>
<div>
<br /></div>
<div>
미신러닝</div>
<div>
.수백 수천 토큰 질의를 해하는 모델</div>
<div>
. 도메인 전용 학습이 필요하지 않은 모델</div>
<div>
.10턴 이상 문맥을 고려하지 않는 모델</div>
<div>
<br /></div>
<div>
구축>훈련>평가>개선 흐름을 자동화</div>
<div>
모델의 비용을 계산하고 결과를 봐야함.</div>
<div>
<br /></div>
<div>
Amdahl's law</div>
<div>
무한의 컴퓨팅 자원을 투입해도 20%의 속도 개선이 가능함.</div>
<div>
아니 경제적인 모델: 학습과 추론의 성능 최적화가 곧 비용인 시대</div>
<div>
<br /></div>
<div>
최적화?</div>
<div>
. 모델 최적화</div>
<div>
. 모델러와 소통</div>
<div>
. Framework customizing, JNI 수준까지</div>
<div>
. 확장 CPU Register사용(bert 120ms에서 bert AVX-512 MKL 7ms로 개선)</div>
<div>
<br /></div>
<div>
1만개 서빙?</div>
<div>
. AutoML auto quantization</div>
<div>
. One source multi environment models(네이버 C3DL 기반 동작)</div>
<div>
. Decentralized clusters (kaa) akka, spark, scala, tf</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZVos1uvt6VRxlKVO8iOreEp9cns_C4kJqHQzMqSsyepAK1HnptlLx-y1rF_KGBDga0rRB5z132Whzz0X9ZrIA-skPrc0PWAS4hH-CnNeZvRndWaLOtLBOoNdKPGWIBSSf1ElvSCDnTSou/s1600/20191028_151523.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZVos1uvt6VRxlKVO8iOreEp9cns_C4kJqHQzMqSsyepAK1HnptlLx-y1rF_KGBDga0rRB5z132Whzz0X9ZrIA-skPrc0PWAS4hH-CnNeZvRndWaLOtLBOoNdKPGWIBSSf1ElvSCDnTSou/s640/20191028_151523.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[모바일 얼굴인식, 엔진부터 DEVIEW에 적용하기까지]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/312">https://deview.kr/2019/schedule/312</a></div>
<div>
<br /></div>
<div>
얼굴인식으로 인증 단계 감소</div>
<div>
1:N의 얼굴 인식의 경우 보조 인증을 주로 사용</div>
<div>
<br /></div>
<div>
Face engine</div>
<div>
얼굴 검출 > 특징점 검출 > 얼굴인식 딥러닝</div>
<div>
=>Clova Face</div>
<div>
<br />
얼굴 검출을 위한 모델 얘기는 발표자료 참고<br />
Engine을 Product에 적용하는 얘기도 발표 자료 참고</div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxmAOhq8eSN9cMWU0Dv0Payic5kNai3iCK64C5_lh0Mr3GOYzgSvMA2-fDPX8rt3HyQZaMGntEHu4Tz_Mn0tnY2Sk96VAgh6GVA7thOn8AMsSMMKmAfVq1Fwd3PaRKyAifBf8JfyGGWNO_/s1600/20191028_161536.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxmAOhq8eSN9cMWU0Dv0Payic5kNai3iCK64C5_lh0Mr3GOYzgSvMA2-fDPX8rt3HyQZaMGntEHu4Tz_Mn0tnY2Sk96VAgh6GVA7thOn8AMsSMMKmAfVq1Fwd3PaRKyAifBf8JfyGGWNO_/s640/20191028_161536.jpg" width="640" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
<b>[어디까지 깎아봤니?: 모바일 서비스를 위한 가벼운 이미지 인식/검출 딥러닝 모델 설계]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/321">https://deview.kr/2019/schedule/321</a></div>
<div>
<br /></div>
<div>
발표를 들으며 "발표자는 진정 <strike>방망이</strike>모델 깍는 노인이구나"라는 생각이 머리를 계속 맴돌았음.</div>
<div>
발표자료는 꼭 보시길</div>
<div>
<br /></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOGCqpk142kPdV3N7LyP1sFQf1dZT3wZw_C0j9Jt7H-NLXYeYW_AXL6UJlBlwRlwl6AmZ8tI3vbJC4idBU19nZpPNl5LtMY0CYcwBhKgBikRj9h2BQQ4ZkqBgGX8-TWETsNtWPsrpIoAQ1/s1600/20191028_171437.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOGCqpk142kPdV3N7LyP1sFQf1dZT3wZw_C0j9Jt7H-NLXYeYW_AXL6UJlBlwRlwl6AmZ8tI3vbJC4idBU19nZpPNl5LtMY0CYcwBhKgBikRj9h2BQQ4ZkqBgGX8-TWETsNtWPsrpIoAQ1/s640/20191028_171437.jpg" width="640" /></a></div>
<br /></div>
<div>
<b>[예약 전화도 쉽게 받는 인공지능 비서를 만드는 P;ㅠ]</b></div>
<div>
<br /></div>
<div>
<a href="https://deview.kr/2019/schedule/293">https://deview.kr/2019/schedule/293</a></div>
<div>
<br /></div>
<div>
이분은 회사에서 자주 본 것 같은데 비슷한 사람이었나?</div>
<div>
<br /></div>
<div>
아직도 전화 예약을 많이 한다.</div>
<div>
사람도 전화응대를 잘 못한다.</div>
<div>
스피커, 챗봇과는 다름</div>
<div>
<br /></div>
<div>
Conversation Space</div>
<div>
<br /></div>
<div>
Turn, Sequence, Activity,Task 로 대화를 구분</div>
<div>
<br /></div>
<div>
대화에는 실패가 없다. </div>
<div>
Command control 패턴과 같은 스피커에서와는 다르게 대화를 반복하여 해결 가능</div>
<div>
<br /></div>
<div>
Full duplex <> Gateway >ASR >DNNLU >SYNTH >Gateway</div>
<div>
<br /></div>
<div>
성능향상을 위한 모델</div>
<div>
. Contextual hint</div>
<div>
. Multi turn</div>
<div>
. Task moving</div>
<div>
. Barge in</div>
<div>
<br />
엔지니어링 이슈들<br />
. Latency</div>
<div>
. Initiative Control</div>
<div>
<br /></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-16730861323126247462019-10-28T17:08:00.004-07:002019-10-31T04:31:14.286-07:00DEVIEW 2019 Key Note 메모<div>
Deview key note 메모</div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSH9g4t-NhvBb1xNfcYJMR5Dt-U5FxRHyoIUb7274f_SX5yN7xEwdOIXvXj5KsYS2dNiZ1Gz9CVyl7GiP4nSmfJyFzjUdysJgh_hxeKe2YGEEnWWBugGQpmsHnx6zTIE8VyGuWMD3JymA8/s1600/20191028_084145.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" class=" imageResizeTarget" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSH9g4t-NhvBb1xNfcYJMR5Dt-U5FxRHyoIUb7274f_SX5yN7xEwdOIXvXj5KsYS2dNiZ1Gz9CVyl7GiP4nSmfJyFzjUdysJgh_hxeKe2YGEEnWWBugGQpmsHnx6zTIE8VyGuWMD3JymA8/s640/20191028_084145.jpg" width="640"></a></div>
<br></div>
<div>
<a href="https://www.naverlabs.com/storyDetail/142">https://www.naverlabs.com/storyDetail/142</a></div>
<div>
https://platum.kr/archives/130372</div>
<div>
https://byline.network/2019/10/28-67/</div>
<div>
<br></div>
<div>
<br></div>
<div>
치타 시연 </div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5EkVKHUnSRxyimbjkIgR4Ha5fyfhkkhDSu6n8Uy3ksWfpMGDBuQpnz5VLQw9mgIoZhVQ-slQYN6tWCc69GjtLDyoUVeYU60-yqSR5ms9ORsaynKv2YskHFZavLFLTOqiW4BXhwOX6u7XV/s1600/20191028_095137.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" class=" imageResizeTarget" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5EkVKHUnSRxyimbjkIgR4Ha5fyfhkkhDSu6n8Uy3ksWfpMGDBuQpnz5VLQw9mgIoZhVQ-slQYN6tWCc69GjtLDyoUVeYU60-yqSR5ms9ORsaynKv2YskHFZavLFLTOqiW4BXhwOX6u7XV/s640/20191028_095137.jpg" width="640"></a></div>
</div>
<div>
<br></div>
<div>
<br></div>
<div>
Autonomous space + AI AR Automation</div>
<div>
>> A(utonomous) city</div>
<div>
<br></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA1zxmIk2HX_0bpyYciEgghobKeYOFhiqZnFzdOd-_r0YjvPFwer1jLiwduevbd3xhNMZnApz26fJsGTtxx3UDmSu5ETZiF6RlJbBrNDuluWcs5FW49toUNSYlnygyjwKT8nLgbDUO5ksT/s1600/20191028_095337.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA1zxmIk2HX_0bpyYciEgghobKeYOFhiqZnFzdOd-_r0YjvPFwer1jLiwduevbd3xhNMZnApz26fJsGTtxx3UDmSu5ETZiF6RlJbBrNDuluWcs5FW49toUNSYlnygyjwKT8nLgbDUO5ksT/s640/20191028_095337.jpg" width="640"></a></div>
<br></div>
<div>
<br></div>
<div>
하이브리드 HD 매핑</div>
<div>
인도어, 아웃도어 모두 매핑</div>
<div>
도로 HD MAP DATA 무상 배포</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<br></div>
</div>
<div>
아웃도어 로봇 Alt platform 을</div>
<div>
인도어 로봇 Around platform 와 통합</div>
<div>
<br></div>
<div>
로봇과 제 2 사옥을</div>
<div>
Human friendly Robot & Robot friendly Building 으로</div>
<div>
<br></div>
<div>
Global AI R&D Belt : 한국/일본/프랑스/동남아의 인공지능 연구진과 스타트업, 기관들을 연결</div>
<div>
<br></div>
<div>
새로운 표준</div>
<div>
더 큰 연결의 가능성</div>
<div>
기술 상상 도전</div>
<div>
<br></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br></div>
<div>
수아랩</div>
<div>
퓨리오사AI chip</div>
<div>
<br></div>
<div>
문재인 대통령님 연설</div>
<div>
<a href="https://www.google.com/amp/s/m.yna.co.kr/amp/view/AKR20191028054400001">https://www.google.com/amp/s/m.yna.co.kr/amp/view/AKR20191028054400001</a></div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwBQZb2K6uVGwEoYb0XNa663_ND315OXeWNKF_t_Nb4wXXD1zcVcuMyIkOwsAN09Pza4uwEs7vi3NB8FjbMPTbMC27RosVlJAKccGmELDGnL3xJl_Y3Taq8uPguWA4KGcfrjTldnmUggjN/s1600/20191028_101442.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="4032" data-original-width="3024" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwBQZb2K6uVGwEoYb0XNa663_ND315OXeWNKF_t_Nb4wXXD1zcVcuMyIkOwsAN09Pza4uwEs7vi3NB8FjbMPTbMC27RosVlJAKccGmELDGnL3xJl_Y3Taq8uPguWA4KGcfrjTldnmUggjN/s640/20191028_101442.jpg" width="480"></a></div>
<br></div>
<div>
<br></div>
<div>
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ</div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0IFIUpG_kc2euSpGuTLomv3V5wxRjPlGPHBHOaYnR8cVXeL4vhOkOeRpblDQczopebsSu2_QdqTg1oPW40nZ3GO0AA1_WEobACpnhhoo8KhDVJjEJm0Y9Ig7J34ZOOBGq60R_EcgdCZ6W/s1600/20191028_102544.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0IFIUpG_kc2euSpGuTLomv3V5wxRjPlGPHBHOaYnR8cVXeL4vhOkOeRpblDQczopebsSu2_QdqTg1oPW40nZ3GO0AA1_WEobACpnhhoo8KhDVJjEJm0Y9Ig7J34ZOOBGq60R_EcgdCZ6W/s640/20191028_102544.jpg" width="640"></a></div>
<br></div>
<div>
(네이버 서치)</div>
<div>
<br></div>
<div>
<br></div>
<div>
인플루언서 검색 지원 > 창작자 연결</div>
<div>
AI 기술 - 비전 검색 등등 기술 개발</div>
<div>
"사용자 이해" 네이버 검색 기술의 핵심 가치</div>
<div>
>Deep understanding</div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBVO8kVy1PwTUIFZnYCieRUpTVE1oO9V0lmNgSY404x88qb1pCw-5cF2D_4piiJOCx3qK86SH0n6l1_L5YwundarNaIS49RxOqz1EfnPNLkC4iJHf-dqMI2-kdb5a72VcmC4ojo7VqqivX/s1600/20191028_103412.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBVO8kVy1PwTUIFZnYCieRUpTVE1oO9V0lmNgSY404x88qb1pCw-5cF2D_4piiJOCx3qK86SH0n6l1_L5YwundarNaIS49RxOqz1EfnPNLkC4iJHf-dqMI2-kdb5a72VcmC4ojo7VqqivX/s640/20191028_103412.jpg" width="640"></a></div>
<br></div>
<div>
(네이버 플랫폼)</div>
<div>
<br></div>
<div>
클라우드 네이티브 컴퓨팅</div>
<div>
네이버 컨테이너 클러스트</div>
<div>
<br></div>
<div>
.auto scaling 트래픽 예비자원</div>
<div>
.서버 효율 증대</div>
<div>
<br></div>
<div>
2019년 네이버 서비스 60% 이상 컨테이너 운영</div>
<div>
<br></div>
<div>
Pinpoint 2015년 공개</div>
<div>
+ Nel02? npot?</div>
<div>
+ 지원 생태계 확장</div>
<div>
<br></div>
<div>
클라우드 네이티브 컴퓨팅</div>
<div>
Observability 확대를 위한 서비스</div>
<div>
오픈소스 생태계 지원</div>
<div>
<br></div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl-dIWWEObKoCXn5n7K4th_z_9latgTe8cQB-aiH8uW5-FdX3doBIsoleClIzcmRTjOjtU_VBTIJAOqmpa1vWOWL__zGCOalwmXckpuExHOzpDRJpDUZittr0bLvXOZMa82RQZ5YE_jh8n/s1600/20191028_104022.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl-dIWWEObKoCXn5n7K4th_z_9latgTe8cQB-aiH8uW5-FdX3doBIsoleClIzcmRTjOjtU_VBTIJAOqmpa1vWOWL__zGCOalwmXckpuExHOzpDRJpDUZittr0bLvXOZMa82RQZ5YE_jh8n/s640/20191028_104022.jpg" width="640"></a></div>
<br></div>
<div>
(네이버 클라우드 플랫폼)</div>
<div>
<br></div>
<div>
2014년 부터 퍼블릭 오픈</div>
<div>
<br></div>
<div>
장점</div>
<div>
.국내 자체 기술</div>
<div>
.안정성, 보안 측면</div>
<div>
.클라우드 서비스 대안</div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheA2K9XDIutj2XeuRiVqZtY8h2Y2wqZkoZ7w_Feef_GO3dB6F6v0boTub7cD3ppP9JlowWIHFa6zBTYwfacq_RU_4aOBwc7cP2CfP-I1xvFgaROkplnCgS8R2o5RyP5JIoMf_kyYVOOKY8/s1600/20191028_104744.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheA2K9XDIutj2XeuRiVqZtY8h2Y2wqZkoZ7w_Feef_GO3dB6F6v0boTub7cD3ppP9JlowWIHFa6zBTYwfacq_RU_4aOBwc7cP2CfP-I1xvFgaROkplnCgS8R2o5RyP5JIoMf_kyYVOOKY8/s640/20191028_104744.jpg" width="640"></a></div>
<br></div>
<div>
(네이버 동영상)</div>
<div>
<br></div>
<div>
<br></div>
<div>
2013 </div>
<div>
카메라 ㅡ 인코더 ㅡ 범용미디어버서 ㅡ CDN ㅡ 모바일 플레이어 </div>
<div>
2015</div>
<div>
모바일카메라ㅡ모바일 인코더ㅡ범용미디어서버</div>
<div>
2018</div>
<div>
모바일카메라ㅡ모바일 인코더ㅡ네이버미디어서버</div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLWH-KnrWm4Y-HloNgigTsW8l_vi8VeYubaYzPc0YUrxUP8GGoNK0sendZTst7wwjCd69lvV5pKk-NXc11sbNPdCP2hy5LFX3wWEw3kyS5MFOqIFQdUD1_pSSOhgGbxwkXFTHFY3TTn-BQ/s1600/20191028_105012.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLWH-KnrWm4Y-HloNgigTsW8l_vi8VeYubaYzPc0YUrxUP8GGoNK0sendZTst7wwjCd69lvV5pKk-NXc11sbNPdCP2hy5LFX3wWEw3kyS5MFOqIFQdUD1_pSSOhgGbxwkXFTHFY3TTn-BQ/s640/20191028_105012.jpg" width="640"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH5UubZcKfLnACff6Yn8JoE7TK76V9_ehKMQArSqo5X8I-4n4wo7ys0UGyw5KNdniMwWfV8jtonh1rB6m1NkUTfuKxIM7b_NZkFZvVZAKjtma2crBKFM2G_4tKgqBHdGgsfvzsgts1uv4j/s1600/20191028_105145.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH5UubZcKfLnACff6Yn8JoE7TK76V9_ehKMQArSqo5X8I-4n4wo7ys0UGyw5KNdniMwWfV8jtonh1rB6m1NkUTfuKxIM7b_NZkFZvVZAKjtma2crBKFM2G_4tKgqBHdGgsfvzsgts1uv4j/s640/20191028_105145.jpg" width="640"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0gu3KUb4_A7rlMe_cg9dzQsPjnjP4YzXejF_QroGRJPS1ndwCAmfsGmYG3mHErksyxIyNvbed1tUmg7ssL4Qj8EPNutz6lZSTWdcXORnDVsH0DExwNyqsQrxm-MUv2riT5D8sFR9UqRa7/s1600/20191028_105407.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0gu3KUb4_A7rlMe_cg9dzQsPjnjP4YzXejF_QroGRJPS1ndwCAmfsGmYG3mHErksyxIyNvbed1tUmg7ssL4Qj8EPNutz6lZSTWdcXORnDVsH0DExwNyqsQrxm-MUv2riT5D8sFR9UqRa7/s640/20191028_105407.jpg" width="640"></a></div>
<br></div>
<div>
2020년 까지 4K</div>
<div>
안드로이드 지원 중, 삼성 스마트 티비 지원 예정</div>
<div>
<br></div>
<div>
<br></div>
<div>
<br>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnFxkj3koskXfkbta8u3CyMeQR0eWOP8VuGRxIr7lbKPnLQPFvBRWOWaAZqQmii8kl0DaMkPQ7QvMdygyQNiBWQ4zDmNvlabsuUpfe_kHHAXzexg5zQbL8_UoFRUfKEJfdUWnF4YlXgx0K/s1600/20191028_105726.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnFxkj3koskXfkbta8u3CyMeQR0eWOP8VuGRxIr7lbKPnLQPFvBRWOWaAZqQmii8kl0DaMkPQ7QvMdygyQNiBWQ4zDmNvlabsuUpfe_kHHAXzexg5zQbL8_UoFRUfKEJfdUWnF4YlXgx0K/s640/20191028_105726.jpg" width="640"></a></div>
<br></div>
<div>
(네이버 AI)</div>
<div>
<br></div>
<div>
사용자를 이해</div>
<div>
사용자에게 감동 제공</div>
<div>
사용자가 편리</div>
<div>
<br></div>
<div>
이해</div>
<div>
.정확하게 듣고 이해 (영상 사용)</div>
<div>
.의도를 정확이 이해 (징면 인지)</div>
<div>
<br></div>
<div>
감동</div>
<div>
.자연스럽게 말하고(감정, 사투리)</div>
<div>
<br></div>
<div>
편리</div>
<div>
.영수증, 고지서 플레이릴스트 OCR</div>
<div>
.얼굴인식</div>
<div>
.Ai Call 음성전화 예약</div>
<div>
<br></div>
<div>
Cloud AI API 제공</div>
<div>
<br></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-7610219017566961862019-10-21T04:15:00.000-07:002019-10-28T04:15:59.586-07:00GDG Devfest 2019 메모<div>
https://festa.io/events/559</div>
<div>
<br /></div>
<div>
발표자료 공유해주시면 감사할텐데..</div>
<div>
이런 행사를 제공하는 것만으로도 감사.</div>
<div>
다만 발표자 역량에 따라 발표내용이...</div>
<div>
<br /></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvbPKOfyil9U2Xmul_mGibgyKljB1lfNOUxHrPrHORVdrNhpB0tTSIWZzCopEiSFu7Q1XgYMGTneDyAdKVB8lGulUwdt44NTftJY3I9fPD4v2lUYbwGYiTDGeUJPgtMbR-lh8dPr8sW8TY/s1600/20191020_125022.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="3024" data-original-width="4032" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvbPKOfyil9U2Xmul_mGibgyKljB1lfNOUxHrPrHORVdrNhpB0tTSIWZzCopEiSFu7Q1XgYMGTneDyAdKVB8lGulUwdt44NTftJY3I9fPD4v2lUYbwGYiTDGeUJPgtMbR-lh8dPr8sW8TY/s400/20191020_125022.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQdFUNHBwca6cgAF8yvkHPA8OvrHFcxOc_qZtpZD34mCo3t4CB0_w4L8s1AIcSud0Cm9_yVu3lJ8YCzlW99Md-Q5NE9KvamFhUC8t3ygkIv2kOmIST2_1-EOhnDdBjwIM2-gxtCallW4pQ/s1600/75347e81-df17-4731-9ed7-d980e515e988.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="2066" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQdFUNHBwca6cgAF8yvkHPA8OvrHFcxOc_qZtpZD34mCo3t4CB0_w4L8s1AIcSud0Cm9_yVu3lJ8YCzlW99Md-Q5NE9KvamFhUC8t3ygkIv2kOmIST2_1-EOhnDdBjwIM2-gxtCallW4pQ/s640/75347e81-df17-4731-9ed7-d980e515e988.png" width="640" /></a></div>
<br />
<br /></div>
<div>
<br /></div>
<div>
[Google Cloud 키노트]</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
시대의 흐름?</div>
<div>
1. Dev & operation </div>
<div>
2. DevOps</div>
<div>
3. Infrastructure as a code</div>
<div>
4. SRE - site reliable engineering</div>
<div>
<br /></div>
<div>
Google cloud에서는 대규모의 여러 구글 서비스들을 지원 중 (Analytics, data, application ,infra 등-구글의 9-10억명 기반 서비스의 기반이기도 함.)</div>
<div>
<br /></div>
<div>
구글의 앱,서비스 제공 원칙</div>
<div>
1. User를 먼저 생각</div>
<div>
2. 기획안의 10배를 고민하고 생각함.</div>
<div>
3. 공유할 수 있는 것들을 모두 공유하라</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
--------------------------------------------------------------------------------</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwSbDg3oE4ixT6Z8e4JOEn9ZpENLBKt20l8-PjBHOhR5NJ22qwB9pc1qDm_KRA6gXdqVZSbwXm5eNYIxWnglZ6l6EgEzKQk1Igu_uYooZFCYNr4-Tp6MC3Rch27BCm_4sQGnQgxp4HlYrK/s1600/cf68aa5b-a3cd-43e6-b5ac-67e8bf3a0d85.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwSbDg3oE4ixT6Z8e4JOEn9ZpENLBKt20l8-PjBHOhR5NJ22qwB9pc1qDm_KRA6gXdqVZSbwXm5eNYIxWnglZ6l6EgEzKQk1Igu_uYooZFCYNr4-Tp6MC3Rch27BCm_4sQGnQgxp4HlYrK/s1600/cf68aa5b-a3cd-43e6-b5ac-67e8bf3a0d85.png" width="320" /></a></div>
<br /></div>
<div>
[안드로이드 기반 AR 세계로의 초대]</div>
<div>
<br /></div>
<div>
안드로이드 7.0 이상</div>
<div>
지원기기가 특정되어 있음</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Android, unity, ios, unreal</div>
<div>
<br /></div>
<div>
Unity - all in one engine</div>
<div>
AR core SDK for unitiy를 다운로드 받음.</div>
<div>
<br /></div>
<div>
Case study</div>
<div>
- Life style </div>
<div>
Streem사에 나온 VR 기반 가전 가이드 서비스</div>
<div>
- Game</div>
<div>
Tend AR 사용자 얼굴로 가상의 물고기를 조정하는 펫 게임</div>
<div>
- real estate</div>
<div>
Curate에서 가구를 배치할 수 있는 서비스</div>
<div>
</div>
<div>
개발 및 학습 팁</div>
<div>
- AR core API reference</div>
<div>
- community : guthub, stack, AR experiments</div>
<div>
<br /></div>
<div>
--------------------------------------------------------------------------------</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLwU0PFIIJ8jFSAogVjjdApZBXFEQTpJMqn632sVX5cMknWLObgxKgggNEfw4rklNjhZvMK4gIoaIasKIwRbxCaxMehQDl8LwKS9OOLvO5BsqKKXAkaQ4pFbcAnD5mxT5dGzMQm0I6TAou/s1600/f90a9385-b40c-42c9-92a0-1ba7be1f20fc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLwU0PFIIJ8jFSAogVjjdApZBXFEQTpJMqn632sVX5cMknWLObgxKgggNEfw4rklNjhZvMK4gIoaIasKIwRbxCaxMehQDl8LwKS9OOLvO5BsqKKXAkaQ4pFbcAnD5mxT5dGzMQm0I6TAou/s1600/f90a9385-b40c-42c9-92a0-1ba7be1f20fc.png" width="320" /></a></div>
<br /></div>
<div>
[Reactive Native와 Flutter를 고민하는 개발자분들에게]</div>
<div>
<br /></div>
<div>
Native platform, hybrid platform</div>
<div>
<br /></div>
<div>
Flutter skia ui 엔진이 모든 위젯을 그림</div>
<div>
디바이스 platform, sdk 종속성 없음</div>
<div>
<br /></div>
<div>
React Native는 Platform 기본 컴포넌트를 활용하여 Platform, sdk 종속성이 있음</div>
<div>
<br /></div>
<div>
React Native는 bridge를 사용하고 플랫폼 종속적은 컴포넌트를 지원하여 이라 플랫폼용 코드 구현이 필요하기도 함.</div>
<div>
<br /></div>
<div>
Flutter도 스타일이 구분되어 있어 각 스타일을 다른 플랫폼에서 유지하기 위해서 분기처리 필요함.</div>
<div>
<br /></div>
<div>
모두 Platform specific code를 위해 platform code를 작성하여 호출함.</div>
<div>
<br /></div>
<div>
App size , </div>
<div>
Android hello world, Flutter 4.5M, Raect Native 7.1M</div>
<div>
Flutter은 engine이 4M</div>
<div>
React native js engine이 5M</div>
<div>
<br /></div>
<div>
iOS</div>
<div>
Flutter 52M, React Native 24M</div>
<div>
Flutter 30M, complied dart module 20M</div>
<div>
Js core 15M</div>
<div>
<br /></div>
<div>
개발자 측면</div>
<div>
.IDE 지원은 충분</div>
<div>
.Hit reload 모두 지원</div>
<div>
<br /></div>
<div>
Dart는 인터프리터가 아닌 컴파일 언어, class 기반으로 중첩 코드 형태로 개발 해야함</div>
<div>
JS - html을 활용하여 개발 가능</div>
<div>
<br /></div>
<div>
Architecture </div>
<div>
F BLoC 패턴, 페이지당 BLoC를 하나씩 개발 필요</div>
<div>
R Flux 패턴, redux 데이터가 한 방향으로 이동, 함수형 프로그래밍에 최적화</div>
<div>
<br /></div>
<div>
3rd party library</div>
<div>
F Package manager</div>
<div>
R NPM</div>
<div>
Reactive native의 라이브러리가 많고 flutter은 많지 않고 퀄리티도 부실함.</div>
<div>
<br /></div>
<div>
예제도 마찬가지</div>
<div>
Flutter은 stack overflow보다 github 이슈에 있는 경우 많음</div>
<div>
<br /></div>
<div>
Flutter</div>
<div>
- Camera library는 사용 못함</div>
<div>
- Google 인증 library는 로그인 수준만 사용 가능</div>
<div>
- video player도 성능 문제, frame drop</div>
<div>
- web view도 성능 문제</div>
<div>
<br /></div>
<div>
--------------------------------------------------------------------------------</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlmiCZbXB5nwC6UBHuKilBPoK22zbKOo0GYVL5L8OZts7-nyYuI6r7isyciIMpjU5EVRhc3-LA62OlRh3Erb4bTc0QbMgno6zTpniZxLqtgrFir0mB4w8eqV4NyKd5foXr26zj_tIVgCG9/s1600/509d4ea5-e613-4cbf-acf5-97a7a4acd8c0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlmiCZbXB5nwC6UBHuKilBPoK22zbKOo0GYVL5L8OZts7-nyYuI6r7isyciIMpjU5EVRhc3-LA62OlRh3Erb4bTc0QbMgno6zTpniZxLqtgrFir0mB4w8eqV4NyKd5foXr26zj_tIVgCG9/s1600/509d4ea5-e613-4cbf-acf5-97a7a4acd8c0.png" width="320" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
[Toy project가 쏘아올린 작은 공]</div>
<div>
<br /></div>
<div>
Pingcloud-cli</div>
<div>
https://github.com/reoim/pingcloud-cli</div>
<div>
<br /></div>
<div>
개인 golang 공부를 사용하기 위해 시작</div>
<div>
결국 뱅크샐러드 취업 및 다른 취업 기회 얻음</div>
<div>
<br /></div>
<div>
- 적절한 커뮤니티네 공유</div>
<div>
- README.md 정리, 최대한 자세히 정리 아니면 문의 폭탄</div>
<div>
<br /></div>
<div>
실력이 증요(자격증, 공부, 컨퍼런스 발표 등), 실력을 알리는 것도 중요(블로그, 링크드인, 커뮤니티 등)</div>
<div>
<br /></div>
<div>
-----------------------------------------------------------------------------</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmUwAqGhWamvrhqJM6msAypTCfjUG1AhCjrU7PVvhHMObo-ywUo6XQMw79Ni7OaWGZc28UTkpPVmT0rGNxGKUSHghTg4FJ_kGoehE-ScRni5tmxRUoxmPOuiV5md6ArANSJJv0deqZHzaq/s1600/41fdca59-6704-4f28-86af-f50199c713a1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmUwAqGhWamvrhqJM6msAypTCfjUG1AhCjrU7PVvhHMObo-ywUo6XQMw79Ni7OaWGZc28UTkpPVmT0rGNxGKUSHghTg4FJ_kGoehE-ScRni5tmxRUoxmPOuiV5md6ArANSJJv0deqZHzaq/s1600/41fdca59-6704-4f28-86af-f50199c713a1.png" width="320" /></a></div>
<br /></div>
<div>
[Declarative(<->imperative) UI patterns]</div>
<div>
<br /></div>
<div>
Declarative programming</div>
<div>
필요한 것을 선언하여 사용 </div>
<div>
<br /></div>
<div>
Declarative UI patterns</div>
<div>
화면에 필요한 컴포넌트를 선언하며 UI로 부터 구현을 분리?</div>
<div>
사용할 컴포넌트를 선언(css선언하듯이)</div>
<div>
<br /></div>
<div>
왜?</div>
<div>
화면 이동 시 개발자 버든을 줄여줌</div>
<div>
게발자는 상태를 정의하면 되고 프레임워크에서 알아서 트랜지션을 처리</div>
<div>
>앱의 기능 구현에 집중</div>
<div>
>적은 코드량</div>
<div>
>예측 가능한 코드</div>
<div>
<br /></div>
<div>
Flexibility</div>
<div>
Data + UI code + behavior로 분리됨</div>
<div>
<br /></div>
<div>
Flutter에서는</div>
<div>
UI = f(state)</div>
<div>
<br /></div>
<div>
Widget 기반으로 개발</div>
<div>
- react에서 영향</div>
<div>
- 현재 state로 보여줄 UI를 표시</div>
<div>
- immutable 선언하여 수정 없이 사용</div>
<div>
<br /></div>
<div>
Flutter render tree</div>
<div>
: 기존 뷰 같은 개념</div>
<div>
Render Object</div>
<div>
: 인스턴스화가 비용이 들어서 render tree가 업데이트 될 경우 재사용함 </div>
<div>
<br /></div>
<div>
React</div>
<div>
- declarative, component base</div>
<div>
- reconciliation(UI component tree를 저정하기 위해 On 알고리즘 사용) - flutter와 유사</div>
<div>
<br /></div>
<div>
Jetpack Compose</div>
<div>
- Event handling을 명확히 > data input으로 event 주입</div>
<div>
<br /></div>
<div>
Swift UI</div>
<div>
- view protocol 정의</div>
<div>
- inheritance 보다는 compsition</div>
<div>
- Modifier로 정의</div>
<div>
<br /></div>
<div>
<br /></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-7371645431930033032019-09-12T07:12:00.001-07:002019-09-12T07:12:06.913-07:00Galaxy Home mini 개봉기갤럭시 홈 미니 개봉기<br />
<br />
<a href="https://blog.naver.com/sunshine_308/221646757628">https://blog.naver.com/sunshine_308/221646757628</a>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-53543966201796360452019-08-27T23:15:00.001-07:002019-08-27T23:15:41.287-07:00Galaxy Home Mini 베타 프로그램<div><div>Galaxy Home Mini</div><div>베타 프로그램</div><div>삼성전자의 스마트 홈 스피커 </div><div>갤럭시 홈 미니를 가장 먼저 경험할 수 있는 기회!</div><div><br></div><div>모집기간 2019. 08. 28(수) ~ 2019. 09. 01(일) </div></div><div><br></div><div>https://www.samsung.com/sec/templateEvent/Home_Mini_Beta/<br></div><div><br></div><div><br><div class="separator" style="clear: both; text-align: center;"><br><div class="separator" style="clear: both; text-align: center;"><table cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjKx1YqmMpXpNU3AA5pyHZo4hmWQW_IKxeaPu1IuqFKK9qcXrp8g9mdhqh4lrQCiuqVLcNy67IS5bagGn_ZOFz90cP7QSXkhCvSOvc-5lpSSqDWXrDCagsT8tORiqoeInd_tOxqqu7SsAm/s1600/20190828_151505.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjKx1YqmMpXpNU3AA5pyHZo4hmWQW_IKxeaPu1IuqFKK9qcXrp8g9mdhqh4lrQCiuqVLcNy67IS5bagGn_ZOFz90cP7QSXkhCvSOvc-5lpSSqDWXrDCagsT8tORiqoeInd_tOxqqu7SsAm/s1600/20190828_151505.jpg" border="0" data-original-width="1080" data-original-height="1596" width="472" height="697" class=" " title="" alt=""></a></td></tr><tr><td class="tr-caption" style="text-align: center;"></td></tr></tbody></table></div><br></div><br></div>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-13258625821479790022019-04-29T03:26:00.000-07:002019-04-29T03:26:07.040-07:00왜 goto문을 사용하는 것이 해로운가?에 대한 글들사실 교재나 강의에서 goto문이 해롭다고만 했지<br />
왜? 에 대해서는 알아볼 생각을 못했던 것 같다.<br />
<br />
찾아보니 다음 글에서 Dijkstra님께서 프로그래머로서의 goto문 사용에 대해서 언급 하시고 이것이 발단되어 많은논쟁들이 있었고 지금의 구전과 같이 전달되고 있었음.<br />
<br />
Go To Statement Considered Harmful, Edsger W. Dijkstra, 1968년<br />
<a href="http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html">http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html</a><br />
<div>
<br /></div>
<div>
영어라서 천천히 읽어 보면 그냥 goto문을 사용하지 말라는 것이 아니지만 goto문을 사용하는 것은 프로그래머로서 s/w 작성하는데 있어 goto문이 적절하지 않다는 얘기 같다.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
이를 한글로 자세히 설명하는 글들은 다음과 같고 아랫글들을 읽어보니 이해가 쉽게 되었음.</div>
<div>
<br /></div>
<div>
<div>
<a href="https://blog.nacyot.com/articles/2015-12-02-programming-is-difficult/">https://blog.nacyot.com/articles/2015-12-02-programming-is-difficult/</a></div>
<div>
<br /></div>
<div>
<a href="https://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=old_talkbox&wr_id=289198">https://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=old_talkbox&wr_id=289198</a></div>
<div>
<br /></div>
<div>
<b>일부 발췌함.</b></div>
<div>
<br /></div>
<div>
<i>이 논문으로 인해 구조적 프로그래밍에 대한 관심이 크게 일기 시작했고, 여러 언어의 형성에 큰 영향을 끼쳤다. 이 논문이 나오고, 이후 10년도 넘게, 아니 지금까지도 이 논문에 대한 논쟁은 그치지 않고 있다. 이 논문의 핵심은 다음 두 문장에 잘 드러나고 있다. </i></div>
<div>
<i><br /></i></div>
<div>
<i>① 우리는(우리의 한계를 알고 있는 현명한 프로그래머처럼) 정적인 프로그램과 동적인 진행과정 간의 개념적인 간격을 최소화하기 위해 최선을 다해야 하고, 그렇게 해서 (텍스트 공간에 펼쳐진) 프로그램과 (시간상에 펼쳐진) 진행 과정 사이의 대응 관계가 가능한 한 명백하게 해야 한다. </i></div>
<div>
<i><br /></i></div>
<div>
<i>② 어떠한 구문(clause)이든, 프로그래머 독립적 좌표계(programmer independent coordinate system)가 진행과정을 여전히 유익하고 편리하게 설명해 줄 수 있어야 한다는 요구 사항을 만족시켜야 한다. </i></div>
<div>
<i><br /></i></div>
<div>
<i>...</i></div>
<div>
<i><br /></i></div>
<div>
<i>독자들도 모두 동의하겠지만 이 논문은 단순히 ‘goto 문을 없애라’는 수준이 아니다. 다익스트라 스스로도 자신이 제안하는 구조적 프로그래밍이 단순히 goto 문 제거 정도로 도매급으로 팔리는 데 심한 불쾌감을 표현했다. 구조적 프로그래밍은 물론이고, 이 논문 역시 시간과 공간의 갭을 줄여 프로그래머가 실수를 덜하고 올바른 프로그램을 좀더 쉽게 만들게 도와주는 것이 중요하다고 역설한다. </i></div>
<div>
<i><br /></i></div>
<div>
<i>...</i></div>
<div>
<i><br /></i></div>
<div>
<i>이 논문의 결론이 현재 어느 정도나 실현됐을까? 일단, 대부분의 언어에서는 goto를 흡수하여 상위 수준의 제어문인 break, continue, exception 등을 지원하게 됐다. 덕분에 우리는 자신도 모르게 안전한 goto를 쓰고 있는 셈이다. 하지만 여전히 goto를 쓰는 언어가 남아 있다. 아직 논쟁은 그치지 않았다. 영원히 끝나지 않을지도 모르겠다. </i></div>
</div>
<div>
<br /></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-3869592545862207112019-04-26T00:48:00.000-07:002019-04-26T00:48:00.547-07:00include, extern C, naming mangling, linking error얼마 전 cpp 파일에서 header를 include 하지 않아서 linking error가 발생한 적이 있어 이에 대해서 찾아봤는데, 찾아보니 간단한 이유였었음.<br />
아무래도 내가 C/C++ 수업에서 설명을 들었을 것 같은데 제대로 공부하지 않고 아무 생각 없이 코딩했던 내가 한심했음.<br />
<br />
먼저 위의 현상이 발생한 원인을 예를 들어 설명하면<br />
a.cpp 파일에서 정의된 test() 함수를 a.h에서 c-style(extern "C")로 선언을 하고<br />
test() 함수를 b.cpp에서 사용하고 있는 상황에서<br />
a.cpp에서 a.h를 include 하지 않으면 test() 함수 naming mangling으로<br />
b.cpp에서 찾을 수 없는 상황이 되어 linking error가 발생하는 것이었음.<br />
<br />
덕분에 아래 내용도 알게 되었으니 위안으로 삼자..<br />
<br />
그리고 아래 내용은 모두 이 책에 정리되어 있음.<br />
<a href="http://www.yes24.com/Product/Goods/23441719?scode=032&OzSrank=1">http://www.yes24.com/Product/Goods/23441719?scode=032&OzSrank=1</a><br />
<br />
---------------------------------------------------------------------------------------------<br />
<a href="https://stackoverflow.com/questions/48211215/how-is-the-header-file-connected-to-the-corresponding-cpp-file">https://stackoverflow.com/questions/48211215/how-is-the-header-file-connected-to-the-corresponding-cpp-file</a><br />
<div>
<br /></div>
<div>
cpp 파일 컴파일 시 header의 선언들에 대한 정의의 위치를 symbol table에 저장하고 컴파일 단위인 transition unit에서 찾지 못한 선언의 경우도 함께 저장한다.</div>
<div>
cpp 파일이 모두 컴파일되고 linking 단계에서 모든 transition unit의 symbol table을 모아서 찾지 못한 선언의 정의도 업데이트하게 된다고 한다.</div>
<div>
<br />
<br /></div>
추가로 MS Visual C++ language guide에서 컴파일 방법과 참조 범위를 설명하고 있는데<br />
<a href="https://docs.microsoft.com/en-us/cpp/cpp/program-and-linkage-cpp?view=vs-2019">https://docs.microsoft.com/en-us/cpp/cpp/program-and-linkage-cpp?view=vs-2019</a><br />
<br />
컴파일 단계에서 각 cpp에 대해서<br />
cpp와 cpp에서 include하는 모든 header를 묶어서 translation unit으로 만든다고 하고<br />
각 translation unit은 독립적이라 compile 시 영향을 주지 않는다고 함.<br />
<br />
전역이나 namespace scope에 정의된 function이나 non-const 전역 변수들은 External linkage라고 하며 모든 translation unit에서 참조가 가능하지만<br />
다른 object(variable, class definition 등)는 Internal linkage라 불리며 해당 object가 정의된 translation unit에서만 참조 가능하다고 함.<br />
<br />
<br />
위에서 설명된 symbol table에 대해서 여러 사례로 보여주고 설명하는 article이다.<br />
<a href="https://www.toptal.com/c-plus-plus/c-plus-plus-understanding-compilation">https://www.toptal.com/c-plus-plus/c-plus-plus-understanding-compilation</a><br />
Symbol table, naming mangling, undefined symbol, header guard, pass by value/reference 등에 대해서 실제 예를 들며 자세히 설명하고 있음.<br />
<div>
<br />
<br />
Naming mangling<br />
<a href="https://en.wikipedia.org/wiki/Name_mangling">https://en.wikipedia.org/wiki/Name_mangling</a></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-14316139517721832772019-02-16T22:28:00.003-08:002019-02-16T22:29:20.092-08:00Google Play Store 업로드를 위해 앱 서명(signing)을 수동으로 하는 방법최근 구글 정책 변경으로 오랜만에 앱을 업데이트하게 되었음.<br />
<a href="https://www.bloter.net/archives/328897">https://www.bloter.net/archives/328897</a><br />
<div>
<br /></div>
거의 손 놓고 있었던 앱이었는데 기한까지 기능을 제거하지 않으면 앱이 제거된다고 하여<br />
내가 사용하기 위해 어쩔 수 없이 업데이트해서 올릴 수밖에 없었음.<br />
앱을 유지만 하는 것도 생각보다 어렵다.<br />
<br />
<br />
Play Store에 올리기 위해 Android Studio에서 앱을 서명하려고 했는데<br />
계속 password verification이 실패했다는 메세지가 나와서 결국 command line에서 수동으로 앱을 서명해서 올렸고 현상의 원인은 파악하지 못했음.<br />
<br />
일단 앱을 서명하는 방법과 command line에서 수동으로 서명하는 방법은 다음과 같다.<br />
<br />
<h4>
앱을 서명하는 방법</h4>
: <a href="https://developer.android.com/studio/publish/app-signing#sign-apk">https://developer.android.com/studio/publish/app-signing#sign-apk</a><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
위 가이드를 보고 따라 하면 되는데 간략히 설명하면</div>
<div class="separator" style="clear: both; text-align: left;">
Android Studio > Build > Generate Signed Bundle / APK 메뉴를 선택한다.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5GLXL02ieNHfrKhEVy-IBFLfSnMbpB7IesYcrKg_IVcP7mDTPrhvBUAIOUmCbg0IfP6r2rvBoh8QaCpz8ar1ygzIuR9hMQNumVZNA6FpKcw2Tkc3X5bLvowIWzavTVoSBjF6rA8HqB0Wy/s1600/sign1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="426" data-original-width="324" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5GLXL02ieNHfrKhEVy-IBFLfSnMbpB7IesYcrKg_IVcP7mDTPrhvBUAIOUmCbg0IfP6r2rvBoh8QaCpz8ar1ygzIuR9hMQNumVZNA6FpKcw2Tkc3X5bLvowIWzavTVoSBjF6rA8HqB0Wy/s320/sign1.PNG" width="243" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
아래 화면에서 자신의 상황에 맞춰 Create new나 Choose existing을 선택하면 된다.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
만약 서명을 위한 key를 새롭게 만든다면 다음을 참고해서 Play Store에 등록하고 업로드용 key로 만들어 등록하여 사용해야 한다.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
기존에 만들어둔 key store를 선택하고 password를 입력하면 Key alias에서 key를 선택할 수 있고 이후 key의 password를 입력하면 된다. 이때 key store password가 틀리면 key alias를 선택할 수 없다. key password가 다르다면 서명이 실패한다.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg00gZ0YqIUg3W4vEvmaqSFFE1zFeuD2lAg5xFNNwdKpR6fFTplGkR_wAsM8aCfy71Id54UX1snH8v90uimiGecl1IjLbUCGg0F2-_EVqzXhYISDw1KHfvc4sdsS7FR4UnZfCOUj2kL1SyN/s1600/sign2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="517" data-original-width="665" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg00gZ0YqIUg3W4vEvmaqSFFE1zFeuD2lAg5xFNNwdKpR6fFTplGkR_wAsM8aCfy71Id54UX1snH8v90uimiGecl1IjLbUCGg0F2-_EVqzXhYISDw1KHfvc4sdsS7FR4UnZfCOUj2kL1SyN/s320/sign2.PNG" width="320" /></a></div>
<br />
다음 화면에서 release를 선택하면 앱 폴더의 build > output > apk > release 폴더에서 서명된 apk를 찾을 수 있다.<br />
<br />
<br />
<h4>
Key Store, 내부 Key 확인 방법</h4>
: <a href="https://docs.oracle.com/cd/E19226-01/821-0027/gfjwc/index.html">https://docs.oracle.com/cd/E19226-01/821-0027/gfjwc/index.html</a><br />
<br />
위처럼 Android Studio에서 key store 와 key를 확인할 수 있지만 다음 방법으로 확인할 수 있고 key 추출도 가능하다.<br />
<br />
<b>- key Store 내부 key 확인 방법</b><br />
> <i>keytool -list -keystore {keystore파일} -v</i><br />
<i> Enter keystore password:</i><br />
<br />
keytool은 JDK 설치 위치에 있으니 아래 글을 참고하세요.<br />
<a href="https://stackoverflow.com/questions/5488339/how-can-i-find-and-run-the-keytool">https://stackoverflow.com/questions/5488339/how-can-i-find-and-run-the-keytool</a><br />
<br />
위 명령어를 실행 한 뒤 지정된 key store의 password를 입력하여 keystore의 정보와 내부 key 목록을 확인할 수 있다.<br />
<br />
<span style="font-size: xx-small;">D:\key>"c:\Program Files\Java\jdk1.8.0_112\bin\keytool.exe" -list -keystore key_android.jks -v</span><br />
<span style="font-size: xx-small;">키 저장소 비밀번호 입력:</span><br />
<span style="font-size: xx-small;"><br /></span>
<span style="font-size: xx-small;">키 저장소 유형: JKS</span><br />
<span style="font-size: xx-small;">키 저장소 제공자: SUN</span><br />
<span style="font-size: xx-small;"><br /></span>
<span style="font-size: xx-small;">키 저장소에 1개의 항목이 포함되어 있습니다.</span><br />
<span style="font-size: xx-small;"><br /></span>
<span style="font-size: xx-small;">별칭 이름: csk</span><br />
<span style="font-size: xx-small;">생성 날짜: 2016. 3. 13</span><br />
<span style="font-size: xx-small;">항목 유형: PrivateKeyEntry</span><br />
<span style="font-size: xx-small;">인증서 체인 길이: 1</span><br />
<span style="font-size: xx-small;">인증서[1]:</span><br />
<span style="font-size: xx-small;">소유자: CN=csk</span><br />
<span style="font-size: xx-small;">발행자: CN=csk</span><br />
<span style="font-size: xx-small;">일련 번호: 312a2964</span><br />
<span style="font-size: xx-small;">적합한 시작 날짜: Sun Mar 13 19:21:02 KST 2016, 종료 날짜: Thu Mar 07 19:21:02 KST 2041</span><br />
<span style="font-size: xx-small;">인증서 지문:</span><br />
<span style="font-size: xx-small;"> MD5: ...(생략)</span><br />
<span style="font-size: xx-small;"> SHA1: ...(생략)</span><br />
<span style="font-size: xx-small;"> SHA256: ...(생략)</span><br />
<span style="font-size: xx-small;"> 서명 알고리즘 이름: SHA256withRSA</span><br />
<span style="font-size: xx-small;"> 버전: 3</span><br />
<span style="font-size: xx-small;"><br /></span>
<span style="font-size: xx-small;">확장:</span><br />
<span style="font-size: xx-small;">... (생략)</span><br />
<br />
<b>- Key Store에서 Key도 추출 가능하다.</b><br />
> keytool -export -keystore {keystore 파일} -alias {key alias이름} -file {추출할 key 파일명}<br />
<i> Enter keystore password:</i><br />
ex) keytool -export -keystore keystore.jks -alias csk -file csk.cer<br />
<br />
<br />
<br />
<b>Command line에서 수동으로 앱 서명 방법</b><br />
: <a href="https://developer.android.com/studio/publish/app-signing#signing-manually">https://developer.android.com/studio/publish/app-signing#signing-manually</a><br />
<br />
Android Studio에서 알아서 해주시면 부득이 한 경우 다음과 같이 진행하면 된다.<br />
<br />
1. 빌드<br />
2. zipalign을 사용하여 APK 정렬<br />
3. apksigner를 사용하여 서명<br />
<br />
<br />
1. 빌드<br />
Android Studio > View > Tool Windows > Terminal 에서<br />
<i><br /></i>
<i> gradlew assembleRelease</i> 실행<br />
<br />
그럼 project_name/module_name/build/outputs/apk/에 module_name-unsigned.apk라는 이름의 APK가 생성된다.<br />
<br />
2. zipalign을 사용하여 APK 정렬<br />
<i>zipalign -v -p 4 my-app-unsigned.apk my-app-unsigned-aligned.apk</i><br />
<br />
참고로 zipalign은 Android SDK의 build tool에 있다.<br />
<a href="https://stackoverflow.com/questions/40004884/cant-find-apksigner-executable-to-manually-sign-apk">https://stackoverflow.com/questions/40004884/cant-find-apksigner-executable-to-manually-sign-apk</a><br />
<br />
3. apksigner를 사용하여 서명<br />
<i>apksigner sign --ks my-release-key.jks --out my-app-release.apk my-app-unsigned-aligned.apk</i><br />
<br />charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-70111955342853650472018-07-26T08:44:00.000-07:002018-07-26T08:44:21.340-07:00Deep learsing note, links배운것 기억나는 선에서 대충 간략히 정리함.<br />
틀릴 수 있음. cross check 필요<br />
<br />
<a href="http://charlie0301.blogspot.com/2018/07/ai-machine-learning-links.html">http://charlie0301.blogspot.com/2018/07/ai-machine-learning-links.html</a><br />
<br />
<br />
<b>Deep learning</b><br />
: <a href="https://en.wikipedia.org/wiki/Deep_learning">https://en.wikipedia.org/wiki/Deep_learning</a><br />
<br />
Deep learning (also known as deep structured learning or hierarchical learning) is part of a broader family of machine learning methods based on learning data representations, as opposed to task-specific algorithms. Learning can be supervised, semi-supervised or unsupervised.<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>Single-Layer Perceptron (단층 퍼셉트론)</b><br />
: <a href="https://en.wikipedia.org/wiki/Perceptron">https://en.wikipedia.org/wiki/Perceptron</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN8VFvgpogKk7Zdjexqv0jZ-Mw0JVg0FRbHW-SF4Gi-KnAmhPQTzrB3xG7qE4oaVXkF9H17YJlFMNRFyLO9QS6N6rEJsATwPAS54mpRKtJDc5SCCiJVAHtuW5m-PpT74cj8mm0T1aMqBEd/s1600/Perceptron.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="530" data-original-width="750" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN8VFvgpogKk7Zdjexqv0jZ-Mw0JVg0FRbHW-SF4Gi-KnAmhPQTzrB3xG7qE4oaVXkF9H17YJlFMNRFyLO9QS6N6rEJsATwPAS54mpRKtJDc5SCCiJVAHtuW5m-PpT74cj8mm0T1aMqBEd/s400/Perceptron.svg.png" width="400" /></a></div>
<br />
<br /></div>
<div>
: 뉴런을 따라 만든 알고리즘 하나의 단위, 여러 input에 대해 output을 출력</div>
<div>
: 계산은 연결된 이전 퍼셉트론과의 Linear Combination + Activation function</div>
<div>
: Linear Combination - 이전 Layer의 연결된 뉴런들의 출력값 * 연결 weight</div>
<div>
: Activation - 이전 뉴런 들과의 Linear Combination 값을 non-linear function을 통해 Activation</div>
<div>
- Activation function들 : Sigmoid, Hyperbolic Tangent (tanh), Rectified Linear Unit (ReLU)<br />
<a href="https://en.wikipedia.org/wiki/Activation_function">https://en.wikipedia.org/wiki/Activation_function</a></div>
<div>
<br />
<table class="wikitable sortable jquery-tablesorter" style="background-color: #f8f9fa; border-collapse: collapse; border: 1px solid rgb(162, 169, 177); color: #222222; font-family: sans-serif; font-size: 14px; margin: 1em 0px;"><tbody>
<tr><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><a href="https://en.wikipedia.org/wiki/Logistic_function" style="background: none; color: #0b0080; text-decoration-line: none;" title="Logistic function">Logistic</a> (a.k.a. Sigmoid or Soft step)</td><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><a class="image" href="https://en.wikipedia.org/wiki/File:Activation_logistic.svg" style="background: none; color: #0b0080; text-decoration-line: none;"><img alt="Activation logistic.svg" data-file-height="60" data-file-width="120" height="60" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Activation_logistic.svg/120px-Activation_logistic.svg.png" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Activation_logistic.svg/180px-Activation_logistic.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Activation_logistic.svg/240px-Activation_logistic.svg.png 2x" style="border: 0px; vertical-align: middle;" width="120" /></a></td><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><span class="mwe-math-element"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="clip: rect(1px, 1px, 1px, 1px); display: none; font-size: 16.52px; height: 1px; opacity: 0; overflow: hidden; position: absolute; width: 1px;"><math alttext="{\displaystyle f(x)=\sigma (x)={\frac {1}{1+e^{-x}}}}" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><annotation encoding="application/x-tex">{\displaystyle f(x)=\sigma (x)={\frac {1}{1+e^{-x}}}}</annotation></semantics></math></span><img alt="{\displaystyle f(x)=\sigma (x)={\frac {1}{1+e^{-x}}}}" aria-hidden="true" class="mwe-math-fallback-image-inline" src="https://wikimedia.org/api/rest_v1/media/math/render/svg/36f792c44c0a7069ad01386452569d6e34fe95d7" style="border: 0px; display: inline-block; height: 5.509ex; vertical-align: -2.171ex; width: 23.457ex;" /></span><sup class="reference plainlinks nourlexpansion" id="ref_logistic1" style="font-size: 11.2px; line-height: 1; unicode-bidi: isolate; white-space: nowrap;"><a class="external autonumber" href="https://en.wikipedia.org/wiki/Activation_function#endnote_logistic1" style="background: none !important; color: #663366; padding: 0px !important; text-decoration-line: none;">[1]</a></sup></td></tr>
</tbody></table>
</div>
<div>
<table class="wikitable sortable jquery-tablesorter" style="background-color: #f8f9fa; border-collapse: collapse; border: 1px solid rgb(162, 169, 177); color: #222222; font-family: sans-serif; font-size: 14px; margin: 1em 0px;"><tbody>
<tr><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><a href="https://en.wikipedia.org/wiki/Hyperbolic_function#Hyperbolic_tangent" style="background: none; color: #0b0080; text-decoration-line: none;" title="Hyperbolic function">TanH</a> </td><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><a class="image" href="https://en.wikipedia.org/wiki/File:Activation_tanh.svg" style="background: none; color: #0b0080; text-decoration-line: none;"><img alt="Activation tanh.svg" data-file-height="60" data-file-width="120" height="60" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Activation_tanh.svg/120px-Activation_tanh.svg.png" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Activation_tanh.svg/180px-Activation_tanh.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Activation_tanh.svg/240px-Activation_tanh.svg.png 2x" style="border: 0px; vertical-align: middle;" width="120" /></a></td><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><span class="mwe-math-element"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="clip: rect(1px, 1px, 1px, 1px); display: none; font-size: 16.52px; height: 1px; opacity: 0; overflow: hidden; position: absolute; width: 1px;"><math alttext="{\displaystyle f(x)=\tanh(x)={\frac {(e^{x}-e^{-x})}{(e^{x}+e^{-x})}}}" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><annotation encoding="application/x-tex">{\displaystyle f(x)=\tanh(x)={\frac {(e^{x}-e^{-x})}{(e^{x}+e^{-x})}}}</annotation></semantics></math></span><img alt="{\displaystyle f(x)=\tanh(x)={\frac {(e^{x}-e^{-x})}{(e^{x}+e^{-x})}}}" aria-hidden="true" class="mwe-math-fallback-image-inline" src="https://wikimedia.org/api/rest_v1/media/math/render/svg/84c428bf21e34ccc0be8becf3443b06a4b61f3ee" style="border: 0px; display: inline-block; height: 6.509ex; vertical-align: -2.671ex; width: 29.682ex;" /></span></td></tr>
</tbody></table>
<table class="wikitable sortable jquery-tablesorter" style="background-color: #f8f9fa; border-collapse: collapse; border: 1px solid rgb(162, 169, 177); color: #222222; font-family: sans-serif; font-size: 14px; margin: 1em 0px;"><tbody>
<tr><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><a href="https://en.wikipedia.org/wiki/Rectifier_(neural_networks)" style="background: none; color: #0b0080; text-decoration-line: none;" title="Rectifier (neural networks)">Rectified linear unit</a> (ReLU)<span style="font-size: 11.2px; white-space: nowrap;"> </span></td><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><a class="image" href="https://en.wikipedia.org/wiki/File:Activation_rectified_linear.svg" style="background: none; color: #0b0080; text-decoration-line: none;"><img alt="Activation rectified linear.svg" data-file-height="60" data-file-width="120" height="60" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Activation_rectified_linear.svg/120px-Activation_rectified_linear.svg.png" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Activation_rectified_linear.svg/180px-Activation_rectified_linear.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Activation_rectified_linear.svg/240px-Activation_rectified_linear.svg.png 2x" style="border: 0px; vertical-align: middle;" width="120" /></a></td><td style="border: 1px solid rgb(162, 169, 177); padding: 0.2em 0.4em;"><span class="mwe-math-element"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="clip: rect(1px, 1px, 1px, 1px); display: none; font-size: 16.52px; height: 1px; opacity: 0; overflow: hidden; position: absolute; width: 1px;"><math alttext="{\displaystyle f(x)={\begin{cases}0&{\text{for }}x<0\\x&{\text{for }}x\geq 0\end{cases}}}" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><annotation encoding="application/x-tex">{\displaystyle f(x)={\begin{cases}0&{\text{for }}x<0\\x&{\text{for }}x\geq 0\end{cases}}}</annotation></semantics></math></span><img alt="{\displaystyle f(x)={\begin{cases}0&{\text{for }}x<0\\x&{\text{for }}x\geq 0\end{cases}}}" aria-hidden="true" class="mwe-math-fallback-image-inline" src="https://wikimedia.org/api/rest_v1/media/math/render/svg/1d25c25758581789c97cdf80d52bf82bbfd0f237" style="border: 0px; display: inline-block; height: 6.176ex; vertical-align: -2.505ex; width: 22.62ex;" /></span></td></tr>
</tbody></table>
<br />
<br /></div>
<div>
<b>Multi-Layer Perceptron (다층 퍼셉트론)</b><br />
<b> </b>: <a href="https://en.wikipedia.org/wiki/Multilayer_perceptron">https://en.wikipedia.org/wiki/Multilayer_perceptron</a></div>
<div>
: 복수의 Perceptron을 연결한 구조</div>
<div>
: Non-linear Activation function + Multi-Layer</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>Artificial Neural Network (인공 신경망)</b><br />
: <a href="https://en.wikipedia.org/wiki/Artificial_neural_network">https://en.wikipedia.org/wiki/Artificial_neural_network</a></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlrxjErUqq03gnsfXmVCLQGf7XY0ZsH0M-OxypQ7DI6eNdfvtIXqRjQn1LvUey5F5gevJv4jKpLM6ZQ3Wg_p56WnCUu3RxEVYiIJY7yvV22G8o1J0uk9Cp7nFxVm56nRjyf6gA0g0KUsVG/s1600/450px-Colored_neural_network.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="541" data-original-width="450" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlrxjErUqq03gnsfXmVCLQGf7XY0ZsH0M-OxypQ7DI6eNdfvtIXqRjQn1LvUey5F5gevJv4jKpLM6ZQ3Wg_p56WnCUu3RxEVYiIJY7yvV22G8o1J0uk9Cp7nFxVm56nRjyf6gA0g0KUsVG/s320/450px-Colored_neural_network.svg.png" width="265" /></a></div>
<br />
<br />
: 다수의 Neuron이 Layer로 연결되어 복잡한 문제를 해결</div>
<div>
: Input Layer > Hidden Layer > Output Layer 로 구성</div>
<div>
- Input Layer : 초기값을 받는 가장 첫번째 Layer</div>
<div>
- Hidden Layer : 중간 단계의 모든 Layer</div>
<div>
- Output Layer : 마지막 Layer로 출력값 계산</div>
<div>
. 결과값을 그대로 받아 Regression</div>
<div>
. Sigmoid를 거쳐 Binary Classification</div>
<div>
. Softmax를 거쳐 K-Class Classification</div>
<div>
: Forward Propagation</div>
<div>
: Back Propagation Algorithm</div>
<div>
=> <a href="https://google-developers.appspot.com/machine-learning/crash-course/backprop-scroll/">https://google-developers.appspot.com/machine-learning/crash-course/backprop-scroll/</a></div>
<div>
</div>
<div>
<br />
<b>Neural Network Learning Process </b><br />
<b>1) Initialization</b><br />
: 학습하고자 하는 Parameter(<span style="background-color: white; color: #545454; font-family: "Apple SD Gothic Neo", arial, sans-serif; font-size: x-small;">θ</span>) 초기값 선정<br />
: Xavier Initialization (for Sigmoid, tanh), He Initialization (for ReLU)<br />
<br />
<b>2) Cost Function</b><br />
: 함수 정의 (Cost Function을 최소화 하도록 학습 진행)<br />
: 용도에 따라 Least Square Error 또는 Cross-Entropy를 사용함.<br />
: Parameter의 많아질 수록 overfitting 현상이 심화 되어 Cost Function + Regularization Term 추가<br />
> <a href="https://en.wikipedia.org/wiki/Regularization_(mathematics)">https://en.wikipedia.org/wiki/Regularization_(mathematics)</a><br />
<img alt="{\displaystyle \min _{f}\sum _{i=1}^{n}V(f(x_{i}),y_{i})+\lambda R(f)}" aria-hidden="true" class="mwe-math-fallback-image-inline" src="https://wikimedia.org/api/rest_v1/media/math/render/svg/d55221bf8c9b730ff7c4eddddb9473af47bb1d1c" style="background-color: white; border: 0px; color: #222222; display: inline-block; font-family: sans-serif; font-size: 14px; height: 6.843ex; vertical-align: -3.005ex; width: 28.839ex;" /><br />
: Overfitting을 방지하기 위한 방법으로 Dropout 방법도 있음.<br />
> <a href="https://en.wikipedia.org/wiki/Convolutional_neural_network#Dropout">https://en.wikipedia.org/wiki/Convolutional_neural_network#Dropout</a><br />
<br />
<b>3) Optimizer</b><br />
: Cost Function을 최소화하는 방향으로 Parameter(<span style="background-color: white; color: #545454; font-family: "Apple SD Gothic Neo", arial, sans-serif; font-size: x-small;">θ</span>)를 변경하는 학습 방식을 적용<br />
: 일반적으로 Gradient Descent를 이용한 방식 사용<br />
: Batch normalization, Optimizer (Adam)<br />
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br />
: <a href="https://www.slideshare.net/HeeWonPark11/ss-80653977">https://www.slideshare.net/HeeWonPark11/ss-80653977</a></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkyA2dxyxWD6dxVAfmX8t0djyWa2soM-Hq_sFwtwCx-Vc7T-59q14ciNDvEIVrlD0H9l2NbBW6B2LkRJStqffAimdRSBq4b3jX0lwiUVM7Sj4CZ9ejyXI0xwQxDEHP0TiQI_Y8NZQhkQEd/s1600/-14-638.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="479" data-original-width="638" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkyA2dxyxWD6dxVAfmX8t0djyWa2soM-Hq_sFwtwCx-Vc7T-59q14ciNDvEIVrlD0H9l2NbBW6B2LkRJStqffAimdRSBq4b3jX0lwiUVM7Sj4CZ9ejyXI0xwQxDEHP0TiQI_Y8NZQhkQEd/s1600/-14-638.jpg" /></a></div>
<br /></div>
<br />charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-1108645046108836202018-07-25T07:34:00.001-07:002018-07-25T08:18:19.287-07:00머신러닝 관련 note, links배운것 기억나는 선에서 대충 간단하게 정리함.<br />
틀릴 수 있음. cross check 필요<br />
<br />
<a href="http://charlie0301.blogspot.com/2018/07/ai-machine-learning-links.html">http://charlie0301.blogspot.com/2018/07/ai-machine-learning-links.html</a><br />
<br />
<br />
<br />
<b>Machine learning</b><br />
: <a href="https://en.wikipedia.org/wiki/Machine_learning">https://en.wikipedia.org/wiki/Machine_learning</a><br />
<br />
Machine learning is a subset of artificial intelligence in the field of computer science that often uses statistical techniques to give computers the ability to "learn" (i.e., progressively improve performance on a specific task) with data, without being explicitly programmed.<br />
<br />
<br />
<div>
<b>머신러닝 분류</b></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeFz9E1IlpLYN8xHR285zN7iIZEo7zLObIjfGX08LvxGQToTKkPOboSjDuvmZYMFfHzAZWKKaC3swPVnpebYN-INdwOzvaLoIMHVGrutqULh1Aa0ed5-h4h2Nmbo3l9L8l3GE8MRrNWhl1/s1600/207.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="572" data-original-width="800" height="456" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeFz9E1IlpLYN8xHR285zN7iIZEo7zLObIjfGX08LvxGQToTKkPOboSjDuvmZYMFfHzAZWKKaC3swPVnpebYN-INdwOzvaLoIMHVGrutqULh1Aa0ed5-h4h2Nmbo3l9L8l3GE8MRrNWhl1/s640/207.jpg" width="640" /></a></div>
<div>
<br /></div>
<div>
: <a href="https://www.techleer.com/articles/203-machine-learning-algorithm-backbone-of-emerging-technologies/">https://www.techleer.com/articles/203-machine-learning-algorithm-backbone-of-emerging-technologies/</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
- <b>Supervised Learning (지도 학습)</b></div>
<div>
: Input에 대한 Output을 예측하기 위해 학습, 정답이 존재</div>
<div>
<br /></div>
<div>
- <b>Unsupervised Learning (비지도 학습)</b></div>
<div>
: Input 데이터에서 패턴을 발견하는 것, 정답이 없음</div>
<div>
<br /></div>
<div>
- <b>Reinforcement Learning (강화 학습)</b></div>
<div>
: Trial & Error를 통한 학습</div>
<div>
<br /></div>
<div>
자세한 내용은 아래 링크 참조</div>
<div>
<br /></div>
<div>
<b>머신 러닝(Machine Learning) 알고리즘 분류 – 지도 학습(Supervised Learning), 비지도 학습(Unsupervised Learning), 강화 학습(Reinforcement Learning) by Solaris</b></div>
<div>
: <a href="http://solarisailab.com/archives/1785">http://solarisailab.com/archives/1785</a></div>
<div>
<br />
<br />
<br />
<b>Output에 따른 분류</b><br />
<br />
- <b>Regression</b><br />
: 결과가 연속값(Continuous value)으로 주어짐, 모델이 그리는 선을 기반하여 결과값을 예측</div>
<div>
<br />
- <b>Logistic Regression, Binary Classification</b><br />
: 결과가 양자 택일 값(Binary value)임<br />
<br />
- <b>Clustering </b><br />
: 결과가 여러개의 불연속값(Multiple discrete value)임<br />
<br />
<br />
<br /></div>
<div>
<b>Machine Learning algorithms/methods 간략 설명</b></div>
<div>
<br /></div>
<div>
: <a href="http://usblogs.pwc.com/emerging-technology/machine-learning-methods-infographic/">http://usblogs.pwc.com/emerging-technology/machine-learning-methods-infographic/</a></div>
<div>
: <a href="https://docs.microsoft.com/ko-kr/azure/machine-learning/studio/algorithm-choice#algorithm-notes">https://docs.microsoft.com/ko-kr/azure/machine-learning/studio/algorithm-choice#algorithm-notes</a></div>
<div>
<br /></div>
<br />
<div>
</div>
- <b>Linear Regression (선형 회귀)</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1ThkiuuiuIGkNR5WE2ilrnkcCwiiINOCFgFLcoWG_xUyuOUZWqB1D0EVYp4HG_AkFElkGJmwbnzFa9fDrHFQyf69vTwK628EjI9PutHIBm-j2QNkwo3tNkl6Iqz6uOADLNw57mC3yQpOF/s1600/image3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="539" data-original-width="703" height="245" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1ThkiuuiuIGkNR5WE2ilrnkcCwiiINOCFgFLcoWG_xUyuOUZWqB1D0EVYp4HG_AkFElkGJmwbnzFa9fDrHFQyf69vTwK628EjI9PutHIBm-j2QNkwo3tNkl6Iqz6uOADLNw57mC3yQpOF/s320/image3.png" width="320" /></a></div>
<br />
<br />
: y와 한개 이상의 x와의 상관관계를 모델링<br />
: Cost Function (비용 함수), Linear Regression의 경우 Mean square error function(평균 제곱 오차 함수)을 활용<br />
=> Gradient Descent Algorithm(경사하강법, 미분으로 경사를 확인하여 음의 방향으로 이동하여 다시 계산)을 사용해서 Cost가 최소가 되는 지점을 찾음. 이때 적절한 이동을 위해 Learning Rate(학습률)이 중요함.<br />
<br />
<br />
- <b>Logistic Regression (로지스틱 회귀)</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3Ja5THCvEaW6k6OP-nnoEDbljfrmbrnzQENO2uzNNefhrx9vm9wSWFGxlPvNJsd4uxvCFaB_Evk8mGraPbRzMYm645YIJGG0IhSIx7oA1-JSKQ-bEtF7ThkSenmmrqoIjJuLrxEBxF013/s1600/image4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="539" data-original-width="673" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3Ja5THCvEaW6k6OP-nnoEDbljfrmbrnzQENO2uzNNefhrx9vm9wSWFGxlPvNJsd4uxvCFaB_Evk8mGraPbRzMYm645YIJGG0IhSIx7oA1-JSKQ-bEtF7ThkSenmmrqoIjJuLrxEBxF013/s320/image4.png" width="320" /></a></div>
<br />
: 이진 분류(binary classification) 문제를 해결하기 위한 모델<br />
: Sigmoid Function을 이용하여 특정 데이터가 positive/negative class에 속할 확률을 계산<br />
: Cross-entropy를 비용함수로 설정하고 Gradient-based optimizer를 통해 학습을 진행함.<br />
<br />
<br />
- <b>Softmax Algorithm (소프트맥스 알고리즘)</b><br />
<br />
: 다중 클래스 분류 문제(Multi-class)를 위한 알고리즘<br />
: Logistic Regression을 변형/발전시킨 방법으로 binary class에서 multiple class 문제로 일반화<br />
<br />
- <b>Support Vector Machine (SVM, 서포트 벡터 머신)</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgks5Edp2BiCSAb3FQDe37V0HiEG7hUbZBmEDOPRRoN5KnJmFO7X7edjaLZdNq8XT5NUju5EtTISmsVFeutc3_wz2Y4sq8ushF6hd4Y80id9HCryppbNVwoLADkz-7sirqBRLmcmwUEDyak/s1600/image7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="578" data-original-width="743" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgks5Edp2BiCSAb3FQDe37V0HiEG7hUbZBmEDOPRRoN5KnJmFO7X7edjaLZdNq8XT5NUju5EtTISmsVFeutc3_wz2Y4sq8ushF6hd4Y80id9HCryppbNVwoLADkz-7sirqBRLmcmwUEDyak/s320/image7.png" width="320" /></a></div>
<br />
: 패턴 인식을 위한 지도 학습 모델, 주로 분류를 위해 사용<br />
: Soft-Margin SVM => margin을 최대화 하는 분류 경계면을 찾는 기법<br />
=> Plus & Minus plain에 여유 변수를 두어 Robustness를 향상<br />
: Kernel Support Vector Machines => margin을 최대화 하는 분류 경계면을 찾는 기법<br />
=> 데이터가 선형적으로 분리되지 않ㅇ르 경우 고차원 공간으로 변환하여 해결<br />
<br />
<br />
등등등...<br />
<br />charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-23843956674010090552018-07-24T04:10:00.001-07:002018-07-26T08:35:58.108-07:00AI 관련 note, links<div>
배운것 기억나는 선에서 대충 간략히 정리함.<br />
틀릴 수 있음. cross check 필요</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>Artificial intelligence</b></div>
<div>
: <a href="https://en.wikipedia.org/wiki/Artificial_intelligence">https://en.wikipedia.org/wiki/Artificial_intelligence</a></div>
<div>
<br /></div>
<div>
<b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">Artificial intelligence</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> (</span><b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">AI</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">), sometimes called </span><b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">machine intelligence</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">, is </span><a href="https://en.wikipedia.org/wiki/Intelligence" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Intelligence">intelligence</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> demonstrated by </span><a href="https://en.wikipedia.org/wiki/Machine" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Machine">machines</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">, in contrast to the </span><b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">natural intelligence</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> displayed by humans and other animals. In </span><a href="https://en.wikipedia.org/wiki/Computer_science" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Computer science">computer science</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> AI research is defined as the study of "</span><a href="https://en.wikipedia.org/wiki/Intelligent_agent" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Intelligent agent">intelligent agents</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">": any device that perceives its environment and takes actions that maximize its chance of successfully achieving its goals.</span></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>Machine learning</b></div>
<div>
: <a href="https://en.wikipedia.org/wiki/Machine_learning">https://en.wikipedia.org/wiki/Machine_learning</a></div>
<div>
<br /></div>
<div>
<b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">Machine learning</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> is a subset of </span><a href="https://en.wikipedia.org/wiki/Artificial_intelligence" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Artificial intelligence">artificial intelligence</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> in the field of </span><a href="https://en.wikipedia.org/wiki/Computer_science" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Computer science">computer science</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> that often uses statistical techniques to give </span><a href="https://en.wikipedia.org/wiki/Computer" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Computer">computers</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> the ability to "learn" (i.e., progressively improve performance on a specific task) with </span><a href="https://en.wikipedia.org/wiki/Data" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Data">data</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">, without being explicitly programmed.</span></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>Deep learning</b></div>
<div>
: <a href="https://en.wikipedia.org/wiki/Deep_learning">https://en.wikipedia.org/wiki/Deep_learning</a></div>
<div>
<br /></div>
<div>
<b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">Deep learning</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> (also known as </span><b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">deep structured learning</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> or </span><b style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">hierarchical learning</b><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">) is part of a broader family of </span><a href="https://en.wikipedia.org/wiki/Machine_learning" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Machine learning">machine learning</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> methods based on </span><a class="mw-redirect" href="https://en.wikipedia.org/wiki/Learning_representation" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Learning representation">learning data representations</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">, as opposed to task-specific algorithms. Learning can be </span><a href="https://en.wikipedia.org/wiki/Supervised_learning" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Supervised learning">supervised</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">, </span><a href="https://en.wikipedia.org/wiki/Semi-supervised_learning" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Semi-supervised learning">semi-supervised</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;"> or </span><a href="https://en.wikipedia.org/wiki/Unsupervised_learning" style="background: none rgb(255, 255, 255); color: #0b0080; font-family: sans-serif; font-size: 14px; text-decoration-line: none;" title="Unsupervised learning">unsupervised</a><span style="background-color: white; color: #222222; font-family: sans-serif; font-size: 14px;">.</span></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
뭔소린지 모르겠음.</div>
<div>
아래 NVIDIA 글이 설명이 잘 되어 있음.</div>
<div>
<br /></div>
<div>
<div>
<b>인공 지능과 머신 러닝, 딥 러닝의 차이점을 알아보자, NVIDIA KOREA</b></div>
</div>
<div>
: <a href="http://blogs.nvidia.co.kr/2016/08/03/difference_ai_learning_machinelearning/">http://blogs.nvidia.co.kr/2016/08/03/difference_ai_learning_machinelearning/</a></div>
<div>
<div>
<br /></div>
<div>
<b>What’s the Difference Between Artificial Intelligence, Machine Learning, and Deep Learning?, MICHAEL COPELAND</b></div>
</div>
<div>
: <a href="https://blogs.nvidia.com/blog/2016/07/29/whats-difference-artificial-intelligence-machine-learning-deep-learning-ai/">https://blogs.nvidia.com/blog/2016/07/29/whats-difference-artificial-intelligence-machine-learning-deep-learning-ai/</a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwXKx0rM3IhdaZdICDmhOqXbAmWjHSZqxGZHKLF6Z2TIR2N9YdiR2thoiqJJpCgT-QxNsFd_ibl10Ara3cwqWEqMywFReAhdDoq3Ck6VTykl_UZZ9p-kYc3lSQZSaModBcdXy3d4fHbe2q/s1600/postfiles8.naver_.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="468" data-original-width="740" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwXKx0rM3IhdaZdICDmhOqXbAmWjHSZqxGZHKLF6Z2TIR2N9YdiR2thoiqJJpCgT-QxNsFd_ibl10Ara3cwqWEqMywFReAhdDoq3Ck6VTykl_UZZ9p-kYc3lSQZSaModBcdXy3d4fHbe2q/s320/postfiles8.naver_.png" width="320" /></a></div>
<div>
위 기사에서 발췌</div>
<div>
<span style="background-color: white; color: #464646; font-family: "dinpro" , "arial" , "helvetica" , sans-serif; text-align: justify;"><i>인간의 감각, 사고력을 지닌 채 인간처럼 생각하는 인공 지능을 ‘일반 AI(General AI)’라고 하지만, 현재의 기술 발전 수준에서 만들 수 있는 인공지능은 ‘<b><span style="font-size: large;">좁은 AI(Narrow AI)’</span></b>의 개념에 포함됩니다. 좁은 AI는 소셜 미디어의 이미지 분류 서비스나 얼굴 인식 기능 등과 같이 특정 작업을 인간 이상의 능력으로 해낼 수 있는 것이 특징이죠.</i></span></div>
<div>
<i><br /></i></div>
<div>
<span style="background-color: white; color: #464646; font-family: "dinpro" , "arial" , "helvetica" , sans-serif; text-align: justify;"><i><b><span style="font-size: large;">머신 러닝</span></b>은 기본적으로 알고리즘을 이용해 데이터를 분석하고, 분석을 통해 학습하며, 학습한 내용을 기반으로 판단이나 예측을 합니다.</i></span></div>
<div>
<i><br /></i></div>
<div>
<span style="background-color: white; color: #464646; font-family: "dinpro" , "arial" , "helvetica" , sans-serif; text-align: justify;"><i><b><span style="font-size: large;">딥 러닝</span></b>은 인공신경망에서 발전한 형태의 인공 지능으로, 뇌의 뉴런과 유사한 정보 입출력 계층을 활용해 데이터를 학습합니다. </i></span></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
- 머신러닝과 딥러닝의 주요 차이점 중 하나는 머신러닝을 위해서는 Feature 제공하여 학습을 하는데 반해 딥러닝은 모델 내부에 Feature extractor가 존재함.</div>
<div>
: <a href="https://www.analyticsvidhya.com/blog/2017/04/comparison-between-deep-learning-machine-learning/">https://www.analyticsvidhya.com/blog/2017/04/comparison-between-deep-learning-machine-learning/</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>참고 사이트</b></div>
<div>
- 모두를 위한 머신러닝/딥러닝 강의</div>
<div>
: <a href="http://hunkim.github.io/ml/">http://hunkim.github.io/ml/</a></div>
<div>
<br /></div>
<div>
- 머신러닝 단기집중과정</div>
<div>
: <a href="https://developers.google.com/machine-learning/crash-course/">https://developers.google.com/machine-learning/crash-course/</a></div>
<div>
<br />
- Machine Learning 강의노트<br />
: <a href="https://wikidocs.net/book/587">https://wikidocs.net/book/587</a><br />
<br /></div>
<div>
- <span style="background-color: white; color: #24292e; font-family: , "blinkmacsystemfont" , "segoe ui" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px;">밑바닥부터 시작하는 딥러닝</span></div>
<div>
: <a href="https://github.com/WegraLee/deep-learning-from-scratch">https://github.com/WegraLee/deep-learning-from-scratch</a><br />
- [개앞맵시] 스카이넷도 딥러닝부터</div>
<div>
: <a href="https://www.mindmeister.com/ko/812276967/_?fullscreen=1">https://www.mindmeister.com/ko/812276967/_?fullscreen=1</a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0tag:blogger.com,1999:blog-7260596801258397336.post-86032568446867856882018-07-23T07:39:00.002-07:002018-07-23T09:11:57.707-07:00[Links] Pandas links, 복습...이미 정리된 사이트들이 많아 그냥 찾아서 링크함.<br />
<br />
10 Minutes to pandas<br />
: <a href="https://pandas.pydata.org/pandas-docs/stable/10min.html">https://pandas.pydata.org/pandas-docs/stable/10min.html</a><br />
<br />
Python - Pandas 튜토리얼 1(데이터프레임 생성, 접근, 삭제, 수정), Deep Play<br />
: <a href="http://3months.tistory.com/292">http://3months.tistory.com/292</a><br />
<br />
PANDAS(판다스) 기초 정리<br />
: <a href="http://doorbw.tistory.com/172">http://doorbw.tistory.com/172</a><br />
<br />
<br />
복습으로 서울시 인구 수를 Pandas를 가지고 확인해봄.<br />
제대로 했는지 모르겠음.<br />
: <a href="https://colab.research.google.com/github/hallower/pandas_study/blob/master/seoul_people_count/Age.ipynb">https://colab.research.google.com/github/hallower/pandas_study/blob/master/seoul_people_count/Age.ipynb</a>charliehttp://www.blogger.com/profile/11815420077164234854noreply@blogger.com0