特征与虚拟开销
Traits vs virtual overhead
我看到了关于特质的 Alexandrescu 教程,我有一些想法要分享。这是代码:
// Example 6: Reference counting traits
//
template <class T>
class RefCountingTraits
{
static void Refer(T* p)
{
p->IncRef(); // assume RefCounted interface
}
static void Unrefer(T* p)
{
p->DecRef(); // assume RefCounted interface
}
};
template <>
class RefCountingTraits<Widget>
{
static void Refer(Widget* p)
{
p->AddReference(); // use Widget interface
}
static void Unrefer(Widget* p)
{
// use Widget interface
if (p->RemoveReference() == 0)
delete p;
}
};
与标准的虚函数成员案例相比,我们在这种情况下有多少开销?在这种情况下,我们也没有直接访问对象:我们仍然传递一个指针。编译器是否能够以相同的方式对其进行优化?
在典型的生产优化级别(-O2
或 /O2
),您可以预期您显示的所有代码都是内联的,并且没有副作用的位被优化掉。剩下对 IncRef
或 AddReference
的实际调用以及对 delete
-ion.
的检查
如果使用了 virtual
函数,并且如果引用计数代码很简单(例如,线程不安全),由于分派 table 它可能会慢一个数量级查找和线外函数调用,但这会因编译器、精确优化设置、CPU、调用约定等而略有不同。
一如既往,当您需要关心、剖析和实验时。
我看到了关于特质的 Alexandrescu 教程,我有一些想法要分享。这是代码:
// Example 6: Reference counting traits
//
template <class T>
class RefCountingTraits
{
static void Refer(T* p)
{
p->IncRef(); // assume RefCounted interface
}
static void Unrefer(T* p)
{
p->DecRef(); // assume RefCounted interface
}
};
template <>
class RefCountingTraits<Widget>
{
static void Refer(Widget* p)
{
p->AddReference(); // use Widget interface
}
static void Unrefer(Widget* p)
{
// use Widget interface
if (p->RemoveReference() == 0)
delete p;
}
};
与标准的虚函数成员案例相比,我们在这种情况下有多少开销?在这种情况下,我们也没有直接访问对象:我们仍然传递一个指针。编译器是否能够以相同的方式对其进行优化?
在典型的生产优化级别(-O2
或 /O2
),您可以预期您显示的所有代码都是内联的,并且没有副作用的位被优化掉。剩下对 IncRef
或 AddReference
的实际调用以及对 delete
-ion.
如果使用了 virtual
函数,并且如果引用计数代码很简单(例如,线程不安全),由于分派 table 它可能会慢一个数量级查找和线外函数调用,但这会因编译器、精确优化设置、CPU、调用约定等而略有不同。
一如既往,当您需要关心、剖析和实验时。