Поскольку вы упоминаете 18% затрат на вызовы vf, я предполагаю, что в каждом классе много виртуальных функций. В этом случае можно попробовать это:
base * pObj;
switch(pObj->getTypeIdentifier())
{
case 1:
static_cast<derivedtype1*>(pObj)->func1;
static_cast<derivedtype1*>(pObj)->func2;
...
case 2:
static_cast<derivedtype2*>(pObj)->func1;
static_cast<derivedtype2*>(pObj)->func2;
...
}
Это в основном то, что виртуальная диспетчеризация делает для каждого func1, func2 и т. Д. Разница здесь в том, что вам нужно переключаться только один раз, даже если вы получаете доступ к нескольким функциям - эквивалент одной виртуальной диспетчеризации.