According to widely spread advice, I should watch out to keep my larger software projects as modular as possible. There are of course various ways to achieve this, but I think that there is no way around to using more or less many interface classes.
Take, as an example the development of a 2D game engine in C++.
Now, one could of course achieve a very modular system by using interfaces for practically everything: From the renderer (Interface Renderer Class -> Dummy, OpenGL, DirectX, SDL, etc.), over audio to input management.
Then, there is the option of making extensive usage of messaging systems, for example. But logically these again come with a high price in performance.
How am I supposed to build a working engine like this?
I don't want to lower the limits for my engine in terms of performance (maximum viable amount of entities, particles, and so on) just to have a perfectly modular system working in the background. This matters because I'd also like to target mobile platforms where CPU power and memory are limited.
Having an interface for the renderer class, for example, would involve virtual function calls for time-critical drawing operations. This alone would slow the engine down by a fair amount.
And here come my main questions:
Where am I supposed to draw the line between consistency and performance with modular programming?
What ways are there to keep projects modular, while retaining good performance for time-critical operations?