Сами виртуальные вызовы занимают больше времени, чем обычные вызовы, потому что они должны искать адрес фактической функции для вызова из vtable
Кроме того, оптимизация компилятора, такая как встраивание, может быть сложной из-за требования поиска. Ситуации, когда встраивание само по себе невозможно, могут привести к довольно высоким издержкам из-за операций выталкивания стека и операций push и jump
Вот правильное исследование, в котором говорится, что накладные расходы могут достигать 50% http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf
Вот еще один ресурс, который рассматривает побочный эффект от наличия большой библиотеки виртуальных классов http://keycorner.org/pub/text/doc/kde-slow.txt
Диспетчеризация виртуальных вызовов с несколькими наследованиями зависит от компилятора, поэтому реализация в этом случае также будет иметь значение.
Что касается вашего конкретного вопроса, касающегося большого количества базовых классов, то обычно макет памяти объекта класса будет содержать vtbl ptrs для всех других составляющих классов внутри него.
Проверьте эту страницу для примера макета vtable - http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html
Таким образом, вызов метода, реализованного классом, более глубоким в иерархии, все равно будет только одной косвенной ссылкой, а не множественной косвенной, как вам кажется. Вызов не должен перемещаться от класса к классу, чтобы, наконец, найти точную функцию для вызова.
Однако, если вы используете композицию вместо наследования, каждый вызов указателя будет виртуальным вызовом, и будут присутствовать дополнительные издержки, и если в этом виртуальном вызове этот класс использует больше compositio, то будет сделано больше виртуальных вызовов. Такой дизайн будет медленнее в зависимости от количества звонков, которые вы сделали.