I was just contemplating about why I improve performance by baking additional details into the object rather than just rendering the more detailed model. How does the GPU get to take a shortcut to render potentially the same amount of detail on screen, just because the detail is represented in a different way?
Reading the comments I think I've understood what @Viziionary was asking, and that's my answer:
First one of your assumption is wrong: normal mapping gives us just an approximation which is clearly visible on edges for examples, like @Sidar said, and like any other approximation is easy to compute.
Second the real point of the answer: 4M vertices will always be 4M vertices (which are more than the pixel on a 1080p screen) and each of them needs to be computed every frame, in the vertex shader. Instead the amount of pixel being drawn may vary a lot (they're generated in the rasterizer stage given the size of the triangles, which change with the distance, on the screen) but to reach the order of milions you need to draw you're model on the whole screen, thing that, in games, nether happens... So with normal maps you're computing only the information (level of detail) you need (the light on the visible pixels) based on the resolution of you're screen/distance of objects/visibility..., while with a detailed mesh you're always computing all the vertices, even if two of them are so close they will be rendered in the same pixel.
Not to mentions that if you move the work on you're pixel shader you can take advantage of things such early-Z (don't remember if this is its name) and other gpu/programming optimisations.
Sorry for the bad english. Hope I've been clear enough.
The problem is that the density of your mesh needs to be higher. Which requires more computational power and memory ( also think of lower end targets/devices ). Additional not ideal for rigged meshes. Normal maps contain surface direction per pixels, the perpendicular direction of the position on the surface ( hence the name normal maps ). Each pixel represents a unit vector, not a color ( it makes a color but that isn't the intend ). With this information it's possible to fake light shading and give the illusion of depth/height similar to a dense mesh while keeping the mesh low poly.
It's fairly cheap to calculate the math in the shaders to get the final result affected by a normal map. Add on top that your mesh is actually pretty low poly in comparison it's a win win for your GPU.
To get a nice effect from your normal map your mesh still needs to have enough density. Normal maps don't curve well on hard edges and completely destroys the illusion.
Edit: I'm assuming you are using a lower poly version of your mesh. If not, that ain't right. Pretty much defeats the purpose otherwise.
4 million triangles vs 500 triangles. That's 0.0125% of the original.