Our website uses cookies to enhance your browsing experience.
Accept
to the top
close form

Fill out the form in 2 simple steps below:

Your contact information:

Step 1
Congratulations! This is your promo code!

Desired license type:

Step 2
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement
close form
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
* By clicking this button you agree to our Privacy Policy statement

close form
Free PVS‑Studio license for Microsoft MVP specialists
* By clicking this button you agree to our Privacy Policy statement

close form
To get the licence for your open-source project, please fill out this form
* By clicking this button you agree to our Privacy Policy statement

close form
I am interested to try it on the platforms:
* By clicking this button you agree to our Privacy Policy statement

close form
check circle
Message submitted.

Your message has been sent. We will email you at


If you do not see the email in your inbox, please check if it is filtered to one of the following folders:

  • Promotion
  • Updates
  • Spam

Webinar: C++ semantics - 06.11

>
>
>
V4002. Unity Engine. Avoid storing cons…
menu mobile close menu
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Micro-Optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C#)
Problems related to code analyzer
Additional information
toggle menu Contents

V4002. Unity Engine. Avoid storing consecutive concatenations inside a single string in performance-sensitive context. Consider using StringBuilder to improve performance.

Aug 02 2023

The analyzer has detected the opportunity to optimize concatenation operations inside a frequently called method.

The concatenation causes the creation of a new string object. As a result, extra memory is allocated in a managed heap. To improve performance, you need to avoid concatenations inside frequently executed code. If you need to repeatedly add various fragments to a string value, the Unity developers recommend to use the 'StringBuilder' type instead of concatenation.

Consider the example:

[SerializeField] Text _stateText;
....
void Update()
{
  ....
  string stateInfo = ....;
  ....
  stateInfo += ....;
  stateInfo += ....;
  ....
  stateInfo += ....;
  _stateText.text = stateInfo;
  ....
}

Here the construction of the 'stateInfo' string is implemented by several concatenation operations. Executing the code in the 'Update' method (which is called several dozen times per second), you will get rapid accumulation of 'garbage' in memory and that's why the garbage collector is frequently called to clean it up. Calling the garbage collector lots of times can have a negative impact on the performance. You can avoid extra memory allocation by using the 'StringBuilder' object:

[SerializeField] Text _stateText;
....
StringBuilder _stateInfo = new StringBuilder();

void Update()
{
  _stateInfo.Clear();
  ....
  _stateInfo.AppendLine(....);
  _stateInfo.AppendLine(....);
  ....
  _stateInfo.AppendLine(....);
  _stateText.text = _stateInfo.ToString();
  ....
}

The 'Clear' method clears the 'StringBuilder' content, but does not release the allocated memory. Thus, the extra memory allocation will be required only if the already used memory is insufficient to store the new text.

Consider another example:

[SerializeField] Text _text;
....
List<string> _messages = new();
....
void LateUpdate()
{
  ....
  string message = BuildMessage();
  _text.text = message;
  _messages.Clear();
}

string BuildMessage()
{
  string result = "";
  foreach (var msg in _messages)
    result += msg + "\n";
  return result;
}

In this example, the 'BuildMessage' method helps generate the message displayed on the interface. Since this method is called inside 'LateUpdate' (as often as inside 'Update'), it's worth optimizing too:

StringBuilder _message = new StringBuilder();

string BuildMessage()
{
   _message.Clear();
   foreach (var msg in _messages)
     _message.AppendLine(msg);

   return _message.ToString();
 }