Granularity is indeed a key issue.
If all of your algorithms are making decisions at a very coarse level, then run-time polymorphism will often do the job. Something we've found though is that if you have the ability to do very fine grained polymorphism, you can do lots of interesting things to help make your code both abstract and fast. Yes, though since compilers that implement these generic techniques well are pretty new, the amount of experience with this sort of thing is pretty thin. There are plusses and minuses to both compile and run time polymorphism. For fine grained polymorphism where you care about performance you have to use compile-time polymorphism.