DEV Community

Mariem Moalla
Mariem Moalla

Posted on

C# Performance Hack: Use record struct for Small, Immutable Models

When designing data models in C#, the choice between class, struct, and record, can significantly impact performance, and memory usage.

But what makes record struct such a good fit for lightweight models compared to classes?


Classes: The Default Choice

By default, most developers reach for class. Classes are reference types:

  • They live on the heap.
  • Variables hold references (pointers) to objects.
  • Garbage Collection (GC) must clean them up when no longer used.

Advantage: Good for large, complex objects that are shared or mutated.
Disadvantage: Overkill for small, short-lived, immutable data models.

Structs

A struct is a value type:

  • Allocated on the stack.
  • Copied by value, not reference.
  • Faster for small, short-lived objects.
  • No GC overhead for stack allocations.

Advantage: Ideal for lightweight data carriers.
Disadvantage: But normal struct lacks the immutability and equality benefits of record.

Records

  • A reference type.
  • Record classes behave similarly to regular classes in terms of memory allocation (on the heap) and assignment (reference copying).
  • Value-based equality (== compares properties, not references).
public record Point(int X, int Y); var p1 = new Point(5, 10); var p2 = new Point(5, 10); var p3 = new Point(10, 20); Console.WriteLine(p1 == p2); // True (same values) Console.WriteLine(p1 == p3); // False (different values) // For classes: public class PointClass { public int X { get; init; } public int Y { get; init; } } var c1 = new PointClass { X = 5, Y = 10 }; var c2 = new PointClass { X = 5, Y = 10 }; Console.WriteLine(c1 == c2); // False (different references) Record Struct : The Best of Both Worlds Combines the performance of a struct (stack-allocated, lightweight). With the features of a record (immutability, value equality, with expressions). public readonly record struct Point(int X, int Y); var p1 = new Point(10, 20); var p2 = new Point(10, 20); // Value equality Console.WriteLine(p1 == p2); // True // With-expression works var p3 = p1 with { X = 30 }; Console.WriteLine(p3); // Point { X = 30, Y = 20 } 
Enter fullscreen mode Exit fullscreen mode

This makes record struct perfect for lightweight models.

When to Use Record Struct 
Enter fullscreen mode Exit fullscreen mode

Use record struct when:

  • You need small, immutable, value-like models.
  • You care about low memory and avoiding heap/GC overhead.

Stick to class when:

  • Objects are large, complex, or mutable.
  • You need shared instances.

Top comments (0)