在阅读问题之前:
这个问题不是关于使用 dynamic_cast
有多大用处。它只是关于它的性能。
我最近开发了一种设计,其中经常使用 dynamic_cast
。
在与同事讨论时,几乎每个人都说 dynamic_cast
不应该使用,因为它的性能很差(这些同事有不同的背景,在某些情况下彼此不认识。我’我在一家大公司工作)
我决定测试这种方法的性能,而不是仅仅相信它们。
使用了以下代码:
ptime firstValue( microsec_clock::local_time() );
ChildObject* castedObject = dynamic_cast<ChildObject*>(parentObject);
ptime secondValue( microsec_clock::local_time() );
time_duration diff = secondValue - firstValue;
std::cout << "Cast1 lasts:\t" << diff.fractional_seconds() << " microsec" << std::endl;
上面的代码在 Linux 上使用来自 boost::date_time
的方法来获取可用值。
我在一次执行中完成了 3 dynamic_cast
,测量它们的代码是相同的。
1次执行的结果如下:
Cast1 持续时间:74 微秒
Cast2 持续时间:2 微秒
Cast3 持续时间:1 微秒
第一次施法总是花费 74-111 微秒,同一执行中的以下施法花费 1-3 微秒。
所以最后我的问题:
dynamic_cast
真的表现不佳吗?
根据测试结果它不是。我的测试代码正确吗?
为什么这么多开发人员认为如果不是,它就很慢?
原文由 MOnsDaR 发布,翻译遵循 CC BY-SA 4.0 许可协议
首先,您需要测量的性能不仅仅是几次迭代,因为您的结果将取决于计时器的分辨率。尝试例如 100 万+,以建立具有代表性的图片。此外,除非您将其与某些东西进行比较,即进行等效但没有动态转换,否则该结果是没有意义的。
其次,您需要通过优化同一个指针上的多个动态转换来确保编译器不会给您错误的结果(因此使用循环,但每次使用不同的输入指针)。
动态转换会比较慢,因为它需要访问对象的 RTTI(运行时类型信息)表,并检查转换是否有效。然后,为了正确使用它,您需要添加错误处理代码来检查返回的指针是否为
NULL
。所有这些都占用了周期。我知道你不想谈论这个,但“一个经常使用 dynamic_cast 的设计”可能表明你做错了什么……