2010-07-28 3 views
1

구조 생성자 사용 두 코드 블록이 성능면에서 동일합니까? 생성자와.net의 구조 생성자 : 오버 헤드가 있습니까?

:

 
Dim pt As Point 
For i As Integer = 1 To 1000 
    pt = New Point(i, i) 
Next 

없음 생성자 없습니다 :

 
Dim pt As Point 
For i As Integer = 1 To 1000 
    pt.X = i 
    pt.Y = i 
Next 

먼저 하나가 생성자 이상의 인수를했을 특히, 짧은이지만,이 게임을 가정 해 봅시다 (루프에서 사용하는 것이 현명하다 루프 초당 60 번 발사)? 또는 두 개가 동일한 기계 코드로 컴파일 되었습니까?

답변

6

타이밍이 코드는 실제로 가능하지 않습니다. 릴리스 버전의 코드를 실행하면 실제 타이밍 결과 만 얻을 수 있습니다. JIT 옵티 마이저에서도 작동합니다. 그리고 "pt"가 실제로 어디에서도 사용되지 않는다는 것을 알기에 충분히 영리합니다. 은 코드를 할당하는 모든 코드를 제거합니다 (). 당신은 똑같은 시간으로 끝날 것이고 여전히 아무것도 모릅니다.

강제로 JIT Optimizer가 실제로 지정 코드를 방출하게하려면 "pt"로 무언가를해야합니다. Like :

하지만 이제는 할당 효율에 대해 알아 내려고하지 않고 Console.WriteLine()이 소요되는 시간을 알 수 있습니다. 이 경우 가치가있는 것은 생성 된 기계 코드를 보는 것입니다. 여기 내 86 JIT 컴파일러가 사용 최적화 빌드 릴리스에서 발생하는 어떤 주석 버전입니다 :

00000008 xor   eax,eax        ; New Point 
0000000a mov   dword ptr [ebp-10h],eax    ; pt.X = 0 
0000000d mov   dword ptr [ebp-0Ch],eax    ; pt.Y = 0 
[first fragment] 
00000010 mov   esi,1         ; i = 1 
      pt = New Point(i, i) 
00000015 mov   dword ptr [ebp-10h],esi    ; pt.X = i 
00000018 mov   dword ptr [ebp-0Ch],esi    ; pt.Y = i 
[elided] 
00000036 add   esi,1         ; i = i + 1 
00000039 jo   0000007D        ; overflow check 
0000003b cmp   esi,3E8h        ; i <= 1000? 
00000041 jle   00000015        ; Yes: loop 
[2nd fragment] 
00000043 mov   esi,1         ; i = 1 
      pt.X = i 
00000048 mov   dword ptr [ebp-10h],esi    ; pt.X = i 
      pt.Y = i 
0000004b mov   dword ptr [ebp-0Ch],esi    ; pt.Y = i 
[elided] 
00000069 add   esi,1         ; i = i + 1 
0000006c jo   0000007D        ; overflow check 
0000006e cmp   esi,3E8h        ; i <= 1000? 
00000074 jle   00000048        : Yes: loop 

에서 [생략] 섹션은 Console.WriteLine() 호출입니다. 기계 코드 지침을 자세히 살펴보십시오.

정확한 코드는입니다.

JIT 컴파일러는 멋진 방식입니다. 동일한 작업을 수행하도록 요청하면 동일한 코드가 생성됩니다. 일반적인 조언은 효율성 대신 명확성을위한 코드 작성입니다. 그러한 진술은 종종 검증되지는 않지만 종종 정확합니다.

+0

감사합니다. 나는 이와 같은 대답을 얻기를 희망했다. 나는 명확성을 위해 코드를 작성하는 것을 좋아하지만 오래된 "이 최적의 것"은 계속 내 머리 속에 터져 나옵니다. –

1

내가 Point을 가정하는 것은 .NET 구조입니다,이 같은 시스템 코드를 제공하겠습니다 것 (값 형식, 참조 형식 반대), 그리고 Point 생성자를 가정하는 것은 아무것도하지 않습니다하지만 XY 필드에 할당 . JIT가 Point 생성자를 인라인으로 연결할 것으로 기대합니다.

그러나 IL은 컴파일러가 생성자를 인라인하지 않기 때문에 IL에 차이가 있습니다. 예상했던대로 첫 번째 코드는 생성자를 1000 번 호출하는 반면 두 번째 코드는 1000 쌍의 필드 저장 연산을 수행합니다.

언제나 "어느 쪽이 빠릅니까?" 질문을하고, 둘 다 적어보고 시간을 잰다. Stopwatch이 유용합니다.

관련 문제