Changing materials through script efficiently

So I have a bunch of primitive cubes, and I need to be able to change the texture on them pretty frequently. I have read that this is very CPU intensive and I would like to be able to fix this (and learn how to fix this) before I get too far into the game. I read that texture atlas-ing was a way to go about this, and that you would need to do UV maps for every mesh, however since I need to change the materials at runtime is this possible? I don’t have any experience UV mapping so I don’t even know if this is possible.

Let’s say I have 9 cubes in 3 sets of 3 with each set having its own texture. Can I change one of the cubes to another texture without changing material(if this is indeed the problem) or changing the two of its former set at the same time?

tempCube.GetComponent<Renderer>().material = bricks[Maze[i,j] - 1];

This is the line I am using to change the material.
Side question: I read that the GetComponent method is fairly expensive, but I am needing a reference to all of my cubes because they all have a chance at changing textures. Can this be done another way, perhaps get an array of them at start or is that impractical?

The way that the atlas situation works is that you take all of the textures you want to use and, on a brand new big texture, you line them all up side-by-side, above or beneath each-other (trying to arrange them nicely, if possible). Then, applying a piece of that atlas to a mesh is like drawing a little marquee box around an image in Paint and saying “only this area is going to be on this object”.

The entire atlas is loaded into memory right away- it won’t change- you just decide on a situational basis which objects need which little sections of that atlas at which times. So short answer- you can change them as often as you like, at runtime or whenever, and it won’t matter much, because it’s just moving that selection marquee around and one place is as good as any.

You can pre-create the UV map areas to correspond to different sections of the atlas that used to be separate textures before they were atlassed (this is usually done as the atlas is being built I think), then simply assign the UVs to an object whenever that particular material is needed. However, my understanding of this process is somewhat limited, so I won’t be able to give you any particulars. I do recall that anything that you do that needs to effect an entire texture (like transparency) won’t work well on an atlas, because the entire atlas is one texture and it’s being shared by dozens of very different-looking objects now. So yeah, there are costs.

You can absolutely store an array of Renderers. If you have some sort of a GameObject array and the Renderers are all that you’re actually using from them, you can just turn it into a Renderer array and skip the GameObject step completely (if you still need the GameObjects themselves, you can access them with someCubeRenderer.gameObject).

I did this, and it seems to have made it slower? Ill post the profiler before and after screenshots in a moment.

Edit: with VSync off it made it slower for some reason, but with VSync on it made it a bit faster.
Before changes: Screenshot - 492343339f9ff7199c753d9d49859ba4 - Gyazo
After changes: Screenshot - b82d41e0526aa4459e186fe5462ac9a9 - Gyazo