Jump to content
Xtreme .Net Talk

Recommended Posts

  • Leaders
Posted

Another chapter in my never ending quest to micro-optimize. Anyone up for a long read?

 

I was thinking about structs. I make a lot of use of them, because I hate to create garbage collected objects when they aren't neccessary. I prefer to let the memory be reclaimed when they go out of scope and save the memory used to manage the object. (Of course, I use classes when they are appropriate, too.)

 

But I was wondering about using struct constructors. When you use the StructInstance = New Struct syntax, I would image that a new struct is allocated on the stack, initialized to default values, the constructor is called, then the newly allocated struct is assigned to the original. If you were to create a static intialization method, however, you could avoid the creation and intialization of a new struct on the stack.

 

I reasoned, however, that the inefficiencies of using a constructor to assign a value to a struct would be optimized out. Of course, I had to see for myself. I coded a constructor, and disassembled it, and discovered that indeed, a new struct is allocatated, initialized to default values, the constructor is called (we are essentially initializing twice, here), and then is assigned back to the original struct. I did this with a release build because this is the build that the end-user will be using.

 

I created a test struct with a constructor and a static method both of which could be used to initialize an already allocated struct.

 

Public Structure TestStruct
   'Members 1 through 5
   Dim M1, M2, M3, M4, M5 As Single

   'Using constructor to initialize
   Public Sub New(ByVal A As Single, ByVal B As Single, _
     ByVal C As Single, ByVal D As Single, ByVal E As Single)
       M1 = A
       M2 = B
       M3 = C
       M4 = D
       M5 = E
   End Sub

   'Using shared method to initialize
   Shared Sub StaticInit(ByRef Struct As TestStruct, ByVal A As Single, _
     ByVal B As Single, ByVal C As Single, ByVal D As Single, ByVal E As Single)
       Struct.M1 = A
       Struct.M2 = B
       Struct.M3 = C
       Struct.M4 = D
       Struct.M5 = E
   End Sub
End Structure

 

And of course we have a function to test these two methods:

   Sub Test()
       'Struct to be initialized
       Dim Struct As TestStruct
       'Times to init struct
       Dim Times As Integer = 10000000

       'Test static function
       Dim Start As Integer = System.Environment.TickCount
       For i As Integer = 0 To Times
           TestStruct.StaticInit(Struct, 1, 2, 3, 4, 5)
       Next
       Dim FirstTime As Integer = System.Environment.TickCount - Start

       'Test constructor
       Start = System.Environment.TickCount
       For i As Integer = 0 To Times
           Struct = New TestStruct(1, 2, 3, 4, 5)
       Next
       Dim SecondTime As Integer = System.Environment.TickCount - Start

       'Display results
       MessageBox.Show(FirstTime.ToString & " " & SecondTime.ToString)
   End Sub

Well, I was dissapointed to see that the constructor, the easier and more intuitive method, ran considerably slower than the static intialization function. The results for six runs were as follows (timed in milliseconds, .ctor = constructor):


Run .ctor Static | Run .ctor Static
1 551 160 | 4 521 190
2 531 160 | 5 521 190
3 541 160 | 6 521 190[/Code]

In the last three runs, I reversed the order of the loops, testing the constructor first and then the static method.

 

This also begs the question as to whether one method or the other is faster when initializing a struct when it is allocated, i.e. [font=Courier New]Dim X As New Struct()[/font] vs. [font=Courier New]Dim X As Struct : Struct.Init(X)[/font].

 

Using a similar test, these are the results that I got, again, switching the order of the tests on the second set of runs:

[Code]
Run .ctor Static | Run .ctor Static
1 360 170 | 4 441 170
2 351 160 | 5 351 170
3 350 170 | 6 361 170[/Code]

It looked a little better for the constructor in the second test, but still disappointing. Of course, you're wondering when you will need to initialize ten million structs, and of course the answer is never. But maybe knowing that constructors aren't particularly efficient can help you sort out a bottle-neck issue someday, or give your Direct3D game a speed boost when you create hundreds or thousands of vertices.

[sIGPIC]e[/sIGPIC]

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...