Is CompareTag better than gameObject.tag performance wise?


Someone told me that this:

function OnTriggerEnter (other : Collider) {
	var deathMenu = GetComponent("");

	if (other.CompareTag("Lava")) {

Is better than this:

function OnTriggerEnter (other : Collider) {
	var deathMenu = GetComponent("");

	if (other.tag == "Lava") {

Is that true? Thanks.

1 Like

CompareTag compiles to fewer CIL instructions than the direct comparison, for sure: it probably results in a single call to the CompareTag internal function, while the other alternative will need a call to the tag getter function (to get the tag string) and another call to the string comparison function, all of this in CIL (the interpreted language used in .NET applications). Since the tag string must be returned by the getter function, space must be allocated, what takes extra time.

Anyway, the difference probably is very small, but may become significant if a lot of CompareTags is used in Update or OnCollision/TriggerStay, and/or the target machine is a mobile device.

The key difference between tag and compareTag is that compareTag does not result in a heap allocation. In Unity, retrieving strings from game Objects will create a duplicate of the string, which will need to be garbage collected.

The source I found reports a ~27% increase in performance of compareTag(aString) vs. using gameObject.tag == “aString”;

Unity 5 Game Optimization by Chris Dickinson

One other big item no one else mentioned.

CompareTag check to see if the tag actually exists and Unity will throw an error if it doesn’t. Just comparing string won’t do that.

// Summary:
// The tag of this game object.
public string tag { get; set; }

    // Summary:
    //     Is this game object tagged with the tag?
    // Parameters:
    //   tag:
    //     The tag to compare.
    [FreeFunction(Name = "GameObjectBindings::CompareTag", HasExplicitThis = true)]
    public bool CompareTag(string tag);

Note: In most of the unity talks I noticed compare tag with the collider. And about the tag, I used it whenever I want to confirm the tag of the specific gameObject within the script.

What i realised is that, if you have a parent object with the tag “A” and a child object with tag “B”:
you want to run a function when the tag is “B”.
if you use if(other.gameObject.tag ==“B”) , it is not going to return true, because gameobject.tag returns the parent object’s tag. so it’ll return “A” and its false. its not going to run.
But, compareTag(“B”) just returns whatever you’re colliding with. ( even if it has a parent with a different tag.) so it’ll return true.

so compareTag is more like doing this → other.collider.tag.
other.collider.tag returns the collider’s tag, so, in this case it returns"B". as well.

just realised that, so, wanted to share.

Operator comparison will create one more string object, which is to be deleted very soon and that makes it generation 0 on the heap. Microsoft claims garbage collector is blazingly fast on gen0 for .NET Framework, but I don’t know the situation for Mono.

As a veteran software developer I would recommend ignoring such micro optimizations unless it is called more than a hundred times per frame. I think such optimizations are in the category of compiler optimizations.

Now time for shameless marketing :slight_smile: Code Enchanter automatically converts all of your tag operator comparisons to method comparisons from your source code.

For example myObject.tag == “myTag” to myObject.CompareTag(“myTag”)

It has some other performance tricks as well, it’s available on Code Enchanter | Utilities Tools | Unity Asset Store