Есть абстрактный тип:
typedef int (*FruitID)(Fruit);
typedef struct _Fruit {
int type;
FruitID id;
} *Fruit;
typedef struct _Apple {
struct _Fruit base;
} *Apple;
int apple_id(Apple a)
{
return 1;
}
Apple apple_new(void)
{
Apple a = (Apple)malloc(sizeof(struct _Apple));
a->base.type = 1;
a->base.id = (FruitID)apple_id;
return a;
}
int fruit_id_virt(Fruit f)
{
return f->id(f);
}
int fruit_id_nonvirt(Fruit f)
{
switch(f->type) {
case 1:
return apple_id((Apple)f);
case 2:
return orange_id((Orange)f);
}
return 0;
}
Fruit a = (Fruit)apple_new();
Fruit o = (Fruit)orange_new();
for(i = 0; i != 0xFFFFFFF; ++i)
#ifdef VIRT
sum += fruit_id_virt(a) + fruit_id_virt(o);
#else
sum += fruit_id_nonvirt(a) + fruit_id_nonvirt(o);
#endif
с fruit_id_virt: 0m9.644s
c fruit_id_nonvirt: 0m4.849s
ЧЯДНТ, отчего такое падение скорости? Как вызов по указателю может быть медленнее цепочки сравнений? Я уже хотел немного избавиться от if/switch в своем коде (как-то и эстетичнее оно), а тут такое...