A main.cpp that includes all other .cpp files and a build.bat that recompile everything, it's always been instant.
And I do use a some amount of template and constexpr for peripheral setup code (computing all the constant values for GPIO config registers with a nice "DSL" of sort for example).
It all compiles nearly instantly. So you can have large apps that work fine in that space and time.
I haven't debugged the differences in compile options, etc. I suspect it is related to constant data handling differences (they both have the same RTTI, exceptions settings. They both use the same GCC version). But IMHO there can be very wide variation in the size of literally the same code.
In the case of arduino, they don't provide you anything that could be used to flamegraph it, but i suspect it's just recompiling a significant part of mbed each time or something.
The non-Mbed based ones are faster to compile for sure.
[1] The one thing Zephyr does not yet support is std::thread/std::mutex, but it's really easy to make it work in your app because the build system functions properly, so i did and sent them patches as an example. They are working on proper support in the toolchain. Just need to rebuild it with some different config flags and twiddle a few files. MBed fully supports std::thread/etc if i remember right.