Performance Engineering
46.1 Measure First
Imports BenchmarkDotNet.Attributes
Imports BenchmarkDotNet.Running
<MemoryDiagnoser>
Public Class StringBenchmarks
Private ReadOnly _items As String() = Enumerable.Range(0, 1000).Select(Function(i) i.ToString()).ToArray()
<Benchmark(Baseline:=True)>
Public Function Concat() As String
Dim s = ""
For Each i In _items : s &= i : Next
Return s
End Function
<Benchmark>
Public Function Builder() As String
Dim sb As New Text.StringBuilder()
For Each i In _items : sb.Append(i) : Next
Return sb.ToString()
End Function
End Class
' BenchmarkRunner.Run(Of StringBenchmarks)() (run in Release)46.2 VB-Specific Tips
Option Strict On (avoids late binding through NewLateBinding, which is 10–100x slower).
Use AndAlso/OrElse. Prefer .NET methods over Microsoft.VisualBasic legacy functions in hot paths.
Integer overflow checks (add.ovf) cost a little. Consider <RemoveIntegerChecks>true</RemoveIntegerChecks> only for proven hot code (you lose safety).
Select Case on strings compiles to hash-based switches. Fine.
Avoid ReDim Preserve in loops (O(n²)). Use List(Of T).
46.3 General .NET Performance
Reduce allocations: reuse buffers (ArrayPool), avoid boxing (IEquatable(Of T)), use StringBuilder, cache compiled Regex, use FrozenDictionary for read-mostly lookups.
Choose the right data structures and algorithms (big-O first).
Async I/O for throughput. Parallelism for CPU-bound work. Avoid lock contention.
Database: right indexes, fewer round trips, projections, batching, AsNoTracking, SqlBulkCopy.
Startup: ReadyToRun, trimming (careful with reflection), lazy initialization, splash screens doing async loading.
WinForms: SuspendLayout/ResumeLayout, BeginUpdate/EndUpdate, DataGridView virtual mode, double buffering. WPF: UI virtualization, frozen brushes, avoiding binding errors.
VB can consume Span(Of T)/Memory(Of T) APIs in limited ways, but can't declare ref structs or use stackalloc. Put ultra-hot code in C# if needed.