The problem with splitting files in many TUs is that compiler needs to do a lot of redundant work - parsing windows.h, stdlib.h, etc... This time adds up quickly. So even if you need to recompile two or three files, it could (depending on your project structure) take as long or even longer than compiling whole unity build.
In a single-threaded build, this is true. In a multithreaded build with as many cores as translation units, the redundant work isn't a problem because it's being done in parallel, so the total build time will generally be the same as the slowest single translation unit.
It would be best if the compiler itself was multithreaded, of course, but with C++ you have to take what you can get.
Discovering which items to build isn't free. It requires getting the last-modified timestamps on every file that contributes to the build.
True, but in practice this is always going to be faster than actually reading and parsing the file, which you have to do during a full rebuild.
It is not uncommon that builds like that get bugged where a object file wasn't rebuild even though it should have been and you need to clean-rebuild. This most often happens when a header is updated and the object file wasn't marked as depending on that header.
For whatever it's worth, this has never happened to me. -MMD
is very reliable with clang and gcc in my experience. I'd guess that this problem is more common in some build environments than in others.