<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged class</title>
<link>https://coderlegion.com/tag/class</link>
<description>Powered by Question2Answer</description>
<item>
<title>No default constructor exists for class</title>
<link>https://coderlegion.com/26936/no-default-constructor-exists-for-class</link>
<description>&lt;p&gt;
In C++, a default constructor is a constructor that is automatically created by the compiler if no other constructors have been defined for a class. However, if a class has any constructors that have been explicitly defined, the compiler will not create a default constructor for that class. This article will discuss the &lt;span style=&quot;color: #ff04fc;&quot;&gt;&quot;no default constructor exists for class&quot;&lt;/span&gt; error in C++ and provide solutions on how to fix it. Whether you are a beginner or an experienced C++ developer, this article will help you understand the concept of default constructors and how to use them effectively. So, let's dive in and explore the world of C++ constructors!
&lt;/p&gt;&lt;hr&gt;
&lt;div id=&quot;toc-div&quot;&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt; Table of Contents:&lt;a id=&quot;toc-toogle&quot; class=&quot;open&quot;&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;div id=&quot;toc-list&quot;&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#what-is-a-constructor-and-it's-role-in-a-class&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;What is a constructor and it's role in a class?&lt;/span&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#differences-between-default-and-parameterized-constructors&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Differences between default and parameterized constructors&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#working-with-default-constructor-in-c++&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Working with default constructor in C++&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#best-practices-for-using-constructors-in-c++&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Best practices for using constructors in C++&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#comparison-of-default-constructors-in-c++-and-other-programming-languages&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Comparison of default constructors in C++ and other programming languages&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#conclusion&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Conclusion&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#references&quot;&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;References&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;What is a constructor and it's role in a class?&lt;/span&gt;&lt;a id=&quot;what-is-a-constructor-and-it's-role-in-a-class&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A constructor is a special member function of a class that is executed when an object of that class is created. It is used to initialize the state of an object, and its name is always the same as the class name. The purpose of a constructor is to ensure that the object of a class is created in a valid state.&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Differences between default and parameterized constructors&lt;/span&gt;&lt;a id=&quot;differences-between-default-and-parameterized-constructors&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In C++, constructors can be defined with or without parameters. A constructor without parameters is known as a &lt;span style=&quot;color: #ff04fc;&quot;&gt;default constructor&lt;/span&gt;, while a constructor with parameters is known as a &lt;span style=&quot;color: #ff04fc;&quot;&gt;parameterized constructor&lt;/span&gt;. The default constructor is called when an object is created without any arguments, and it is responsible for initializing the object to a default state. On the other hand, a parameterized constructor is called when an object is created with specific arguments, and it is responsible for initializing the object to a specific state based on the arguments passed.&lt;/p&gt;
&lt;p&gt;For example, consider the following class definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt; 
class MyClass {
    int x;
public:
    MyClass() {
        x = 0;
    }
    MyClass(int value) {
        x = value;
    }
};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, &lt;span style=&quot;color: #ff04fc;&quot;&gt;&lt;code&gt;MyClass&lt;/code&gt;&lt;/span&gt; class has two constructors, one default and one parameterized. The default constructor initializes the &lt;span style=&quot;color: #ff04fc;&quot;&gt;&lt;code&gt;x&lt;/code&gt;&lt;/span&gt; variable to &lt;span style=&quot;color: #ff04fc;&quot;&gt;&lt;code&gt;0&lt;/code&gt;&lt;/span&gt;, while the parameterized constructor initializes the &lt;span style=&quot;color: #ff04fc;&quot;&gt;&lt;code&gt;x&lt;/code&gt;&lt;/span&gt; variable to the value passed as an argument.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;
MyClass obj; // calls default constructor and x = 0
MyClass obj1(10); // calls parameterized constructor and x = 10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-purple&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Note&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;It's worth noting that, If a class does not have any constructor defined, the compiler creates a default constructor automatically. However, if the class has any constructor defined explicitly, the compiler will not create a default constructor automatically.&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;This can lead to a problem if a program attempts to create an object of that class without explicitly calling one of the defined constructors.&lt;/p&gt;
&lt;p&gt;For example, consider the following class definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;
class MyClass {
public:
    MyClass(int x) {
        // constructor code
    }
};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the class &lt;span style=&quot;color: #ff04fc;&quot;&gt;&lt;code&gt;MyClass&lt;/code&gt;&lt;/span&gt; has a single constructor that takes an int argument. Because this constructor has been explicitly defined, the compiler will not create a default constructor for the class. As a result, the following code will not compile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;
MyClass myObject;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will result in a compile-time error since we are trying to initialize an object with a default constructor whereas we created a constructor in our class definition without defining a default constructor.&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Working with default constructor in C++&lt;/span&gt;&lt;a id=&quot;working-with-default-constructor-in-c++&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To fix this issue, you can either define a default constructor for the class or create an object of the class by explicitly calling one of the defined constructors. For example, you can define a default constructor for the class as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;
class MyClass {
public:
    MyClass(int x) {
        // constructor code
    }

    MyClass() {
        // default constructor code
    }
};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows you to create an object of the class without any arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;
MyClass myObject;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, you can create an object of the class by explicitly calling one of the defined constructors:&lt;br&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;&lt;br&gt;
MyClass myObject(42);&lt;br&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;
Another way to fix this issue is to use the initialization list to initialize the object by passing the required parameters.
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;
class MyClass {
    int x;
public:
    MyClass(int x) : x(x) {
        // constructor code
    }
};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the object is created and initialized in the same statement.&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Best practices for using constructors in C++&lt;/span&gt;&lt;a id=&quot;best-practices-for-using-constructors-in-c++&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When working with constructors in C++, it is important to follow certain best practices to ensure that your code is efficient, readable, and maintainable. Here are some best practices to keep in mind when using constructors in C++:&lt;br&gt;
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Always initialize member variables&lt;/b&gt;: When defining a constructor, make sure to initialize all member variables to their default or appropriate values. This ensures that the object is created in a valid state.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Avoid duplicating code&lt;/b&gt;: When defining multiple constructors for a class, try to avoid duplicating code across constructors. Instead, use a single constructor and pass default values to the member variables.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Use the initialization list&lt;/b&gt;: Instead of initializing the member variables in the constructor body, use the initialization list to initialize the member variables directly. This is more efficient and prevents the object from being in an invalid state if an exception is thrown.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Make the constructors explicit&lt;/b&gt;: When defining a constructor with a single argument, make the constructor explicit to avoid unexpected type conversions.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Avoid overloading constructors&lt;/b&gt;: Overloading constructors can make the code hard to read and maintain. Instead, use default values for member variables in constructors to allow for more flexibility when creating objects.&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Comparison of default constructors in C++ and other programming languages&lt;/span&gt;&lt;a id=&quot;comparison-of-default-constructors-in-c++-and-other-programming-languages&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When comparing default constructors in C++ to other programming languages, it is important to note that the behavior and implementation of default constructors can vary.&lt;/p&gt;
&lt;p&gt;In some programming languages such as Java, the default constructor is automatically created by the compiler even if other constructors are defined. This means that in Java, the &quot;no default constructor exists for class&quot; error will not occur.&lt;/p&gt;
&lt;p&gt;In other programming languages such as C#, the default constructor is not created by the compiler unless the programmer explicitly defines it. This is similar to the behavior in C++, where the default constructor is not created by the compiler if any other constructors are defined.&lt;/p&gt;
&lt;p&gt;In contrast, in languages like Python, constructors are not mandatory and there is no concept of default constructors. Instead, the initialization of an object can be done using the &lt;span style=&quot;color: #ff04fc;&quot;&gt;&lt;code&gt;__init__()&lt;/code&gt;&lt;/span&gt; method, which is called when an object is created.&lt;/p&gt;
&lt;p&gt;It is important to note that understanding the behavior and implementation of default constructors in different programming languages is crucial, especially when working on projects that involve multiple languages or when transitioning from one language to another. This is because the &quot;no default constructor exists for class&quot; error in C++ can be avoided by using a different programming language with different default constructor behavior.&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;Conclusion&lt;/span&gt;&lt;a id=&quot;conclusion&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When a class has any constructors that have been explicitly defined, the compiler will not create a default constructor for that class. This can lead to a problem if a program attempts to create an object of that class without explicitly calling one of the defined constructors. To fix this issue, you can either define a default constructor for the class or create an object of the class by explicitly calling one of the defined constructors, or use the Initialization list.&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;References&lt;/span&gt;&lt;a id=&quot;references&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;Stroustrup, B. (2013). The C++ Programming Language. Pearson Education.&lt;/li&gt;&lt;li&gt;Deitel, P. J., &amp;amp; Deitel, H. M. (2017). C++ how to program. Pearson.&lt;/li&gt;&lt;li&gt;Lippman, S. B., Lajoie, J., &amp;amp; Moo, B. E. (2014). C++ primer. Addison-Wesley.&lt;/li&gt;&lt;/ul&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/26936/no-default-constructor-exists-for-class</guid>
<pubDate>Sat, 12 Sep 2026 06:47:15 +0000</pubDate>
</item>
<item>
<title>Is Your Game Choking on GC Allocations?</title>
<link>https://coderlegion.com/21847/is-your-game-choking-on-gc-allocations</link>
<description>
&lt;h2 id=&quot;is-your-game-choking-on-gc-allocations-a-guide-to-zero-allocation-data-structures&quot;&gt;Is Your Game Choking on GC Allocations? A Guide to Zero-Allocation Data Structures&lt;/h2&gt;

&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;

&lt;p&gt;You&amp;rsquo;ve optimized your shaders, painstakingly batched draw calls, and even dipped your toes into Unity&amp;rsquo;s Burst Compiler and C# Job System. Yet, your game still experiences inexplicable hitches and stutters, particularly during intense moments. The silent assassin in many Unity games isn&amp;rsquo;t the GPU struggling with pixels, but the &lt;strong&gt;Garbage Collector (GC)&lt;/strong&gt; reclaiming memory from incessant, hidden allocations. Specifically, insidious &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GC.Alloc&lt;/code&gt; calls, often for temporary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt;-based data structures, can disrupt your carefully crafted frame budget, leading to frustrating performance spikes.&lt;/p&gt;

&lt;p&gt;This tutorial will illuminate this common pitfall and provide a robust architectural solution: embracing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; types combined with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; for transient data. By understanding and applying these principles, you can virtually eliminate many &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GC.Alloc&lt;/code&gt; calls from your high-frequency game logic, leading to buttery-smooth frame rates and a fundamentally cleaner, faster codebase.&lt;/p&gt;

&lt;h3 id=&quot;the-culprit-unnecessary-class-allocations&quot;&gt;The Culprit: Unnecessary Class Allocations&lt;/h3&gt;

&lt;p&gt;The core problem stems from the fundamental difference between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; in C#. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; is a reference type, always allocated on the &lt;strong&gt;managed heap&lt;/strong&gt;. When you create an instance of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;, memory is allocated on the heap, and a reference to that memory is returned. When that instance is no longer reachable, it becomes garbage, waiting for the GC to collect it &amp;ndash; an operation that can cause noticeable stalls.&lt;/p&gt;

&lt;p&gt;Consider a common scenario: processing temporary query results or calculating scores for nearby entities every frame. If you use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; to represent these temporary data points and store them in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;, you&amp;rsquo;re incurring a double hit:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; itself is a class&lt;/strong&gt;, though often its internal array can be reused.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; instance (if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt;) added to the list is a separate heap allocation.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let&amp;rsquo;s illustrate with a typical (and problematic) pattern for calculating and processing scores for nearby interactable objects:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// PROBLEM: Class-based data structure&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;InteractableScore&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Constructor or properties often implicitly lead to heap allocations&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InteractableScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Target&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Score&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ScoreCalculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MonoBehaviour&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InteractableScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_currentScores&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InteractableScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_currentScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Clears references, but allocated objects are now garbage&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Imagine GetNearbyInteractables() yields many results&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interactable&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetNearbyInteractables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; 
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CalculateScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interactable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_currentScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InteractableScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interactable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// !!! EACH 'new' is a GC.Alloc !!!&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nf&quot;&gt;ProcessScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_currentScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetNearbyInteractables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... implementation ... */&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CalculateScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... implementation ... */&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ProcessScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InteractableScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... implementation ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Update&lt;/code&gt; loop, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetNearbyInteractables()&lt;/code&gt; returns 10 objects, you&amp;rsquo;ve just made 10 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new InteractableScore()&lt;/code&gt; heap allocations every single frame. Over time, this rapid allocation and deallocation will trigger frequent GC cycles, causing noticeable stutter.&lt;/p&gt;

&lt;h3 id=&quot;the-solution-embrace-structs-and-span&quot;&gt;The Solution: Embrace Structs and Span&lt;/h3&gt;

&lt;p&gt;The solution lies in leveraging value types (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;) and efficient memory slicing (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt;). A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; is a value type, meaning its instances are typically allocated directly on the &lt;strong&gt;stack&lt;/strong&gt; (for local variables) or inline within its containing type (if part of an array or another object). When a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; is copied, its entire data is copied, not just a reference. This means no heap allocation for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; itself, and thus, no GC pressure from its creation.&lt;/p&gt;

&lt;p&gt;For temporary collections of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; data, we combine &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; with a pre-allocated array and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt;. An array, even of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;s, is a reference type allocated on the heap &lt;em&gt;once&lt;/em&gt;. By pre-allocating an array large enough to hold your maximum expected temporary data, you perform a single heap allocation at startup. Then, you fill this array with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; instances. Since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt;s are value types, assigning them to array elements does &lt;em&gt;not&lt;/em&gt; create new heap allocations for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; data itself. Finally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; provides a lightweight, zero-allocation &amp;ldquo;view&amp;rdquo; into a portion of this array, allowing you to process only the relevant data without copying or allocating new collections.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s the refactored, performance-optimized approach:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SOLUTION: Struct-based data structure&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;InteractableScoreData&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// It's a struct!&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ZeroAllocScoreCalculator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MonoBehaviour&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Pre-allocate the buffer ONCE at startup. This is a single heap allocation.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Choose a size appropriate for your maximum expected interactables.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InteractableScoreData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_scoreBuffer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InteractableScoreData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; 

    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentScoreCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Tracks how many valid scores we've added to the buffer&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interactable&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetNearbyInteractables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentScoreCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_scoreBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Prevent out-of-bounds&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CalculateScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interactable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Assigning a struct to an array element does NOT allocate on the heap!&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_scoreBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentScoreCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InteractableScoreData&lt;/span&gt; 
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;Target&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interactable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;Score&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; 
                &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;currentScoreCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Use Span&amp;lt;T&amp;gt; to create a zero-allocation view of the valid data in our buffer&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Span&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InteractableScoreData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentScores&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_scoreBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AsSpan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentScoreCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// Process the scores using the Span&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;ProcessScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetNearbyInteractables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... implementation ... */&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CalculateScore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GameObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... implementation ... */&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Updated to accept Span&amp;lt;T&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ProcessScores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Span&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InteractableScoreData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoreData&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Using 'ref readonly' for even more efficiency&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Process scoreData directly from the buffer without copying&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$&quot;Target: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scoreData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;, Score: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scoreData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this refined code, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_scoreBuffer&lt;/code&gt; is allocated only once when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MonoBehaviour&lt;/code&gt; starts. In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Update&lt;/code&gt;, no new heap memory is allocated for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InteractableScoreData&lt;/code&gt; instances. Instead, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; values are directly assigned into pre-existing slots in the array. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; then provides an incredibly efficient way to iterate over the valid portion of this array without any additional memory allocations.&lt;/p&gt;

&lt;p&gt;This approach not only prevents GC spikes but also significantly improves &lt;strong&gt;cache locality&lt;/strong&gt;. Because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; instances in an array are laid out contiguously in memory, the CPU can process them much faster, leveraging its cache more effectively &amp;ndash; a critical win for data-oriented design.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Eliminating insidious &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GC.Alloc&lt;/code&gt; calls is paramount for achieving consistent, high frame rates in Unity. By consciously choosing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct&lt;/code&gt; over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; for transient, high-frequency data and combining this with pre-allocated buffers viewed through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt;, you can drastically reduce GC pressure. This isn&amp;rsquo;t just about micro-optimizations; it&amp;rsquo;s about adopting a fundamentally cleaner and faster architectural pattern for your game logic. Start treating memory as a finite resource, and your game&amp;rsquo;s performance will thank you.&lt;/p&gt;
</description>
<category>Other</category>
<guid isPermaLink="true">https://coderlegion.com/21847/is-your-game-choking-on-gc-allocations</guid>
<pubDate>Fri, 03 Jul 2026 21:43:02 +0000</pubDate>
</item>
</channel>
</rss>