Structure
This VB.NET keyword is used to represent data. A Structure
's data is found directly in its bytes: Integers, Booleans and DateTimes
are built-in Structures.
When we pass a Structure
to a method, its bytes are copied. Structures are stored on the evaluation stack (not the heap) when used in a method body. This can help (or hurt) performance.
To start, this example has a Structure
called Simple. This Structure
has 3 fields: an Integer, a Boolean
and a Double
. These fields are stored directly as part of the Structure
.
Sub
(a constructor).Structure
, of any type, is used in the same way as an Integer. And an Integer itself is a kind of Structure
.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 Module1
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.
DateTime
structure, as a local, and initialize to a value in the year 2020.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 ModuleD: 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.
Structure
called Box is allocated many times in a loop. The managed heap is not accessed.Class
called Ball is allocated in a similar loop.Structure
took around 2 nanoseconds, and the class
took 8. The Structure
allocates faster.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 ' Version 1: use Structure. 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 ' Version 2: use Class. 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 Module2.26 ns Structure 8.20 ns Class
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.
Usually, structures will decrease program performance. It is often better to use Classes for custom types. For typical programs, I advise avoiding custom structures.
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.