Array Class Collections File String Cast Console Data Directive Enum Exception If Interface Lambda LINQ Loop Nothing Number Process Property Regex Sort StringBuilder Structure Sub Time Windows
A Structure is a value type.
is found directly in its bytes. Integers, Booleans and DateTimes are built-in Structures.
Copies. When we pass a Structure to a method, its bytes are copied each time. Structures are stored on the evaluation stack (not the heap) when used in a method body.
And:This gives Structures performance advantages—and sometimes hurts performance.
To start, this example has a Structure called Simple.
This Structure has three fields:
and a Double. These fields are stored directly as part of the Structure.
And:In Main we create an instance of Simple. We do not need to use a New Sub (a constructor).
So:A Structure, of any type, is used in the same way as an Integer. And an Integer itself is a kind of Structure.
Based on: .NET 4.5 Program that uses Structure: VB.NET Structure Simple Public _position As Integer Public _exists As Boolean Public _lastValue As Double End Structure Module Module1 Sub Main() Dim s As Simple s._position = 1 s._exists = False s._lastValue = 5.5 Console.WriteLine(s._position) End Sub End Module Output 1
Copy. A structure is self-contained in its memory region. So when we assign one Structure local to another, it is copied. And the two values, when changed, do not affect each other.
Here:We create a DateTime structure, as a local, and initialize to a value in the year 2020.DateTime
Then:The local d2 copies the values from "d," but the two locals are separate. When "d" is changed, d2 is not affected.
Program that copies structure: VB.NET Module Module1 Sub Main() ' Create a structure and copy it. Dim d As DateTime = New DateTime(2020, 1, 1) Dim d2 As DateTime = d Console.WriteLine("D: " + d) Console.WriteLine("D2: " + d2) ' Reassign "d" and the copy "d2" does not change. d = DateTime.MinValue Console.WriteLine("D2: " + d2) End Sub End Module Output D: 1/1/2020 D2: 1/1/2020 D2: 1/1/2020
A speed difference between Structure and Class comes from allocation models. A Class reference points to data externally stored. A Structure's data is in the variable itself.
Here:A Structure called Box is allocated many times in a loop. The managed heap is not accessed.
And:All the Box instances are stored in local variable memory. Next a Class called Ball is allocated in a similar loop.For Loops
But:On each iteration the managed heap is accessed. This triggers garbage collection at intervals. This reduces performance.
Program that times Structure: VB.NET Structure Box Public _a As Integer Public _b As Boolean Public _c As DateTime End Structure Class Ball Public _a As Integer Public _b As Boolean Public _c As DateTime End Class Module Module1 Sub Main() Dim m As Integer = 100000000 Dim s1 As Stopwatch = Stopwatch.StartNew For i As Integer = 0 To m - 1 Dim b As Box b._a = 1 b._b = False b._c = DateTime.MaxValue Next s1.Stop() Dim s2 As Stopwatch = Stopwatch.StartNew For i As Integer = 0 To m - 1 Dim b As Ball = New Ball b._a = 1 b._b = False b._c = DateTime.MaxValue Next s2.Stop() Dim u As Integer = 1000000 Console.WriteLine(((s1.Elapsed.TotalMilliseconds * u) / m).ToString("0.00 ns")) Console.WriteLine(((s2.Elapsed.TotalMilliseconds * u) / m).ToString("0.00 ns")) End Sub End Module Output 2.26 ns Structure 8.20 ns Class
Results. Each allocation of the Structure took around 2 nanoseconds. But each allocation of the Class, which has equivalent fields, took 8 nanoseconds.
So:Allocating a Structure in this kind of loop has performance advantages. These might be hard to maintain.
Arguments. The Structure, when passed as an argument to a Function, will be slower. It is larger. The Class is only 4 (or 8) bytes. When more bytes are copied, Function calls are slower.Class
Further:This is not true if the JIT-compiler happens to inline the Function call. We have little control over this.
Usually:Structures will decrease program performance. It is often better to use Classes for custom types.
A summary. Structures are often used for built-in types. Structures are unique in their allocation behavior. Their data, their fields and values, are stored directly inside the variable.