[问题] 为什么CRTP+variant还是比virtual快很多

楼主: ab4daa (nooooooooooooooooooo)   2020-01-02 12:27:59
一开始是看到这篇2013的文章
https://eli.thegreenplace.net/2013/12/05/
the-cost-of-dynamic-virtual-calls-vs-static-crtp-dispatch-in-c/
短: https://reurl.cc/M75jGK
里面只用一个CRTP impl 所以compiler可以直接inline
但是我实际用到virtual是像这样
集中一堆ABC然后全呼叫一遍:
vector<ABC*> bases;
for(auto& it : bases)
it->virtual_func();
改成CRTP的写法大概像这样:
https://godbolt.org/z/LygFKT
我的想像是
visit时不是应该也要先看实际型别是什么
再呼叫相对应函数吗
这跟vtable的行为很像吧
为什么量测时间 CRTP还是比virtual快了5~7倍?
(i5 7400 + vs2019)
我的程度看组语或是看variant header都很痛苦
所以来洗耳恭听大大的教训
感恩
作者: Lipraxde (Lipraxde)   2020-01-02 21:04:00
Vvistor 里的那个 for loop 被优化掉了,155 行的没有https://kheresy.wordpress.com/2017/10/16/cpp17-variant/ <- 我觉得介绍的不错
作者: loveme00835 (发箍)   2020-01-02 23:09:00
variant 做的事情就是用 type code 判断然后再转型,而转型后实际上呼叫的函式是在编译时期就选好的, 你可以自己用 union + type code 实作看看
作者: LPH66 (-6.2598534e+18f)   2020-01-03 04:51:00
CRTP 的“基类”并不是单一个类, 而是每个子类都有一个基类也因此虽然看起来同一段程式码被很多不同子类呼叫但因为基类是模版的关系, 每个基类是分开的这个基类在呼叫子类方法时会确定知道自己负责什么子类(借由 CRTP 继承时给的模版参数, 所以也是编译期就确定的)因此可以省去执行所有判断子类的操作 (如 vtable 等)甚至因为子类型态确定, 呼叫当下的所需要的继承相关操作仅仅只有为求得子类实体的 downcast 而已这个 downcast 也因为是 static_cast 基本上没有判断操作简单说就是, 借由模版把子类型态判断变成编译器的模版选择
作者: saladim (杀拉顶)   2020-01-07 01:47:00
请问个蠢问题...为什么tick() function没有name hiding的问题阿? 谢谢~有时会被要求compiler warning要全修...

Links booklink

Contact Us: admin [ a t ] ucptt.com