Lots of falsehoods, misconceptions, and old myths to fix here.
First, the STL containers and algorithms don't use virtual functions at all. Virtual
functions aren't used much in modern C++ code, particularly in places where it matters how
fast they are or aren't. This isn't so much because people worry much about how fast they
are, but just because they are not often especially useful in low-level code where speed
matters.
Second, whatever overhead is associated with a virtual function call has very little to do
with how many memory accesses occur, and everything to do with pipeline stalls. If the speed
of a virtual function call matters, it's in a loop, and all the relevant memory is in cache.
You might lose a cycle or two loading a memory word, then, but you lose a dozen or two
branching through a pointer because the execution pipeline can't look ahead past that branch.
If you used a function pointer in C, you would suffer precisely the same stall. (There are
further complications I won't get into here.)
So, as rules of thumb: (1) if it matters how fast a virtual function call is, compared to a
regular function call, you're probably doing it wrong; and (2) a virtual function call is
architecturally equivalent to calling through a C function pointer. How much do you use
function pointers in C? That's about how much you should use virtual functions in C++. (If
you're more used to Java... may heaven grant mercy on your soul.)
In practice, the time spent doing virtual function calls has no measurable effect on the speed
of a well-conceived C++ program.