I was told FindWithTag and Find are incredibly inefficient, but what else should I use then?

I’m working on my first game, and need some help.

In this video:

He says that using Find and FindWithTag is inefficient. Why?

Should I just use [SerializeField] gameObject for all of my objects then?

Also, currently in my game, I start all of my ground as “ground_”. So my code would look like:

        if (collision.gameObject.name.Substring(0, 6).Equals("ground"))

Is that okay?

Should I use tags instead?

Or maybe layerMasks? I don’t really know how those work, but is that how most people classify their objects?

I’m no optimization expert, but I’d say in terms of performance, Find() is ok for initializing stuff in Start() or Awake(). Just store the references Find() returns in properties and avoid calling Find() later on in Update methods.
I’d rather worry about relying on string literals for wiring up your objects. Maybe have a centralized location where your objects’ names are stored as constants and reference those. This is less error prone and easier to update down the line.