Reputation: 3730
About using structure constructors; are those two code blocks equal in performance?
With constructor:
Dim pt As Point For i As Integer = 1 To 1000 pt = New Point(i, i) Next
No constructor:
Dim pt As Point For i As Integer = 1 To 1000 pt.X = i pt.Y = i Next
First one is shorter, especially if constructor would have more arguments, but is it wise to use it in loops (let say game loop fired 60 times per second)? Or are those two compiled to the same machine code?
Upvotes: 1
Views: 113
Reputation: 942000
Timing this code isn't really possible. You'll only get realistic timing results if you run the Release version of the code. Which also kicks in the JIT optimizer. And it is smart enough to see that "pt" isn't actually used anywhere, it removes all code that assigns it. You'll end up with the exact same time and still not know anything.
To force the JIT optimizer to actually emit the assignment code, you have to do something with "pt". Like:
Console.WriteLine(pt)
But now you'll be timing how long Console.WriteLine() takes instead of finding out anything about the efficiency of the assignment. What's worthy in this case however is to look at the machine code that's generated. Here's an annotated version of what my x86 JIT compiler generated in the Release build with the optimizer enabled:
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
The [elided] section is the Console.WriteLine() call. Look closely at the machine code instructions:
It is the exact same code.
The JIT compiler is cool that way. If you ask it to do the same job it generates the same code. The common advice is to code for clarity instead of efficiency. While such a statement isn't often verified, it is often accurate.
Upvotes: 6
Reputation: 54764
I'd hope these give the same machine code, assuming Point
is a .NET structure (a value type, as opposed to a reference type), and assuming the Point
constructor does nothing but assign to the X
and Y
fields. I'd expect the JIT to inline the call Point
constructor.
There is, however, a difference in the IL, because the compiler doesn't inline the constructor. As you'd expect, the first piece of code makes 1000 calls to the constructor, whereas the second makes 1000 pairs of field store operations.
As always with "which is faster?" questions, write them both and time them. Stopwatch
is useful for this.
Upvotes: 1