성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - 지연 실행이 꼭 필요한 상황이 아니라면 singleton 패턴에서 DCLP보다는 static 초기화를 권장</h1> <p> 전에도 이에 대해 다룬 적이 있지만,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# Singleton 인스턴스 생성 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/896'>https://www.sysnet.pe.kr/2/0/896</a> </pre> <br /> 이번엔 간단한 성능 테스트를 해보겠습니다. DCLP(Double Checked Locking Pattern)로는 이렇게 코딩하고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class DCLP { static DCLP _instance = null; static object _lock = new (); public int Add(int a, int b) { return a + b; } public static DCLP Instance { get { <span style='color: blue; font-weight: bold'>if (_instance == null)</span> { lock (_lock) { <span style='color: blue; font-weight: bold'>if (_instance == null)</span> { _instance = new(); } } } return _instance; } } } </pre> <br /> static 초기화 처리는 이런 식으로 할 텐데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class CCtor { <span style='color: blue; font-weight: bold'>static CCtor _instance = new CCtor();</span> public int Add(int a, int b) { return a + b; } public static CCtor Instance { <span style='color: blue; font-weight: bold'>get { return _instance; }</span> } } </pre> <br /> DCLP의 경우 코드도 길기 때문에 그냥 봐도 속도 면에서 불리해 보입니다. 게다가 static 초기화의 경우 <a target='tab' href='https://www.sysnet.pe.kr/2/0/1545'>단순한 인스턴스 반환이므로 JIT 컴파일 시 최적화로 인해 in-line 처리</a>를 하므로 사실상 메서드 호출이 아닌, 값을 직접 사용하는 식으로 처리하기 때문에 비교 불가의 성능을 보입니다.<br /> <br /> 아래는 그 <a target='tab' href='https://www.sysnet.pe.kr/2/0/12005'>테스트 결과</a>입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > int count = 1; action(1, "touch-JIT", DCLPLoop, count); action(1, "touch-JIT", CCtorLoop, count); count = 500; action(100000, "DCLPLoop", DCLPLoop, count); action(100000, "CCtorLoop", CCtorLoop, count); /* 출력 결과 touch-JIT : 0 touch-JIT : 0 DCLPLoop : 658 CCtorLoop : 30 */ </pre> <br /> (첨부 파일은 이 글의 예제 코드를 포함합니다.)<br /> <br /> 의미상으로 보면, DCLP의 경우에도 if 문 처리 정도의 부하만 있을 듯하지만, 인라인 시킬 수 없다는 단점으로 인해 메서드 호출의 prologue/epilogue 코드 실행을 동반하면서 적어도 다음의 굵은 폰트 영역에 해당하는 코드는 매번 실행되는 부하를 갖게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public static DCLP Instance 82: { 83: get 84: { <span style='color: blue; font-weight: bold'> 85: if (_instance == null) 00F00CA0 55 push ebp 00F00CA1 8B EC mov ebp,esp 00F00CA3 57 push edi 00F00CA4 83 EC 20 sub esp,20h 00F00CA7 8D 7D DC lea edi,[ebp-24h] 00F00CAA B9 07 00 00 00 mov ecx,7 00F00CAF 33 C0 xor eax,eax 00F00CB1 F3 AB rep stos dword ptr es:[edi] 00F00CB3 83 3D F0 42 DE 00 00 cmp dword ptr ds:[0DE42F0h],0 00F00CBA 74 05 je ConsoleApp2.DCLP.get_Instance()+021h (0F00CC1h) 00F00CBC E8 BF F0 7C 73 call 746CFD80 00F00CC1 33 D2 xor edx,edx 00F00CC3 89 55 E0 mov dword ptr [ebp-20h],edx 00F00CC6 83 3D 7C 35 A9 03 00 cmp dword ptr ds:[3A9357Ch],0 00F00CCD 75 6E jne ConsoleApp2.DCLP.get_Instance()+09Dh (0F00D3Dh) </span> 86: { 87: lock (_lock) 00F00CCF A1 80 35 A9 03 mov eax,dword ptr ds:[03A93580h] 00F00CD4 89 45 E0 mov dword ptr [ebp-20h],eax 00F00CD7 33 D2 xor edx,edx 00F00CD9 89 55 E4 mov dword ptr [ebp-1Ch],edx 00F00CDC 8D 55 E4 lea edx,[ebp-1Ch] 00F00CDF 8B 4D E0 mov ecx,dword ptr [ebp-20h] 00F00CE2 E8 69 77 C2 71 call System.Threading.Monitor.Enter(System.Object, Boolean ByRef) (72B28450h) 88: { 89: if (_instance == null) 00F00CE7 83 3D 7C 35 A9 03 00 cmp dword ptr ds:[3A9357Ch],0 00F00CEE 75 24 jne ConsoleApp2.DCLP.get_Instance()+074h (0F00D14h) 90: { 91: _instance = new(); 00F00CF0 B9 9C 61 DE 00 mov ecx,0DE619Ch 00F00CF5 E8 FA 23 ED FF call CORINFO_HELP_NEWSFAST (0DD30F4h) 00F00CFA 89 45 DC mov dword ptr [ebp-24h],eax 00F00CFD 8B 4D DC mov ecx,dword ptr [ebp-24h] 00F00D00 FF 15 DC 61 DE 00 call dword ptr [Pointer to: CLRStub[MethodDescPrestub]@cdbb715500f004e5 (0DE61DCh)] 00F00D06 8B 45 DC mov eax,dword ptr [ebp-24h] 00F00D09 8D 15 7C 35 A9 03 lea edx,ds:[3A9357Ch] 00F00D0F E8 EC DE 42 73 call 7432EC00 92: } 93: } 00F00D14 90 nop 00F00D15 C7 45 EC 00 00 00 00 mov dword ptr [ebp-14h],offset ConsoleApp2.DCLP.get_Instance()+078h (00h) 00F00D1C C7 45 F0 FC 00 00 00 mov dword ptr [ebp-10h],0FCh 00F00D23 68 48 0D F0 00 push offset ConsoleApp2.DCLP.get_Instance()+0A8h (0F00D48h) 00F00D28 EB 00 jmp ConsoleApp2.DCLP.get_Instance()+08Ah (0F00D2Ah) 00F00D2A 0F B6 45 E4 movzx eax,byte ptr [ebp-1Ch] 00F00D2E 85 C0 test eax,eax 00F00D30 74 08 je ConsoleApp2.DCLP.get_Instance()+09Ah (0F00D3Ah) 00F00D32 8B 4D E0 mov ecx,dword ptr [ebp-20h] 00F00D35 E8 6D DD 42 73 call 7432EAA7 00F00D3A 58 pop eax 00F00D3B FF E0 jmp eax 94: } 95: <span style='color: blue; font-weight: bold'> 96: return _instance; 00F00D3D A1 7C 35 A9 03 mov eax,dword ptr ds:[03A9357Ch] 00F00D42 8D 65 FC lea esp,[ebp-4] 00F00D45 5F pop edi 00F00D46 5D pop ebp 00F00D47 C3 ret </span> </pre> <br /> 이런 면에서 볼 때, '지연 처리'가 절실하게 필요한 상황이 아니라면 static 초기화를 이용한 singleton 처리가 여러모로 장점을 갖습니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
8873
(왼쪽의 숫자를 입력해야 합니다.)