According to this page: C# string.Intern and IsInterned - Dot Net Perls
“It is faster to compare interned strings because the method that C# implements string comparisons with always checks references first. If the references are equal, the comparison succeeds.”
Internally, code supposedly looks like this:
public static bool Equals(string a, string b)
{
return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b)));
}
But this page is describing Microsoft’s CLR.
- Does the same behavior apply to Unity’s version of Mono as well? Does the == operator between strings do a reference compare before the per-character string compare?
- And if so, would GameObject tags be interned at runtime?
Apart from the lack of code completion (although Visual Studio now checks misspellings), I’ve always avoided using and creating string interfaces because of the performance implications. But, barring the lack of code completion, string interfaces are arguably more scaleable and easier to set up, versus setting up reference identification or new enums. Those are really good things to skip if you’re still at prototyping stages.
But if string interning does what it does, we could just have a preparatory step for string member fields where applicable (calling myString = string.Intern(myString);
on initialization), and the resulting reference comparisons from == operators would theoretically make it fast enough even for performance-critical code.
More info: String.Intern(String) Method (System) | Microsoft Learn
EDIT:
I guess to clarify, the insight here was that interned strings might be used to identify certain kinds of data in a collection, for example, if you had a centralized place for playing UI sounds and you wanted to identify sounds by their name.
But I guess in actual use, getting data identified by a string through a string interface would involve either traversing a List and checking each item, or accessing it through a Dictionary.
The List solution is nicer in Unity because Lists serialize. And in this case, you’d still be traversing a List, but one could at least rest easy that you could reliably do reference comparisons object.ReferenceCompare(string1, string2);
if you interned your strings correctly.
I guess the == operator didn’t really matter, 'cause if that fails, it would still attempt the char-by-char comparison.
It just wouldn’t matter in the Dictionary case either since access is through hash values.
I guess this still has other uses somehow.