If you ever worked with basic API like D3D or OpenGL you should now that each device (or context) function call costs time, for example for D3D9 you can find a table about how much each call costs at the end of this page: Accurately Profiling Direct3D API Calls (Direct3D 9) - Win32 apps | Microsoft Docs
You can see top 5: [TABLE]
SetVertexShader
3000 - 12100
SetPixelShader
6300 - 7000
So if you changing shader - it’s costs time.
I am not sure if Unreal is smart enough to compare 2 materials and decide they are equal, if it’s true - then copies of materials not changes performance at run time (because theay are same shader), but compile time for each material keeps same, I can say this for sure since I worked on projects with lot’s of imported assets from the store and each asset had same or almost same material, but unique one.
So, use Material Instance where ever you can use them - it’s saving compiler time and probably run time performance.