What is the difference in performance between MaterialInstace vs Material?

Limiting the number of material shaders can definitely be a boon to performance. Static switch and mask parameters make the distinction a bit unclear so I will try to explain it:

A material with no static switches will generate a set of shaders. All material instances that use the material will use the same set of shaders.

A material with static switches will generate a set of shaders for each unique combination of static switch settings across all material instances that use it. All material instances that use the same set of static switches will use the same set of shaders.

An example, let’s say you have two materials: M_Wood with no static switches and M_Concrete with a single static switch: IsWet. Then say you have a bunch of material instances that use M_Wood, a bunch of material instances that use M_Concrete with IsWet=False, and a bunch of material instances that use M_Concrete with IsWet=True. The engine is going to generate three separate sets of shaders: one set for M_Wood, one set for M_Concrete with IsWet=True, and one set for M_Concrete with IsWet=False. All of the material instances that use the same master material with the same set of static switches will use the same shaders.

My usual recommendation to content teams is that you want to have a simple material with no static switches to use on the bulk of assets in your world, say 90%. You then want to leverage the material editor to make very interesting materials for the other 10%. But it all depends on what you’re trying to achieve, whether you want the performance benefits of material reuse or you are willing to draw fewer meshes but want more variety in materials.