作者ab4daa (nooooooooooooooooooo)
看板C_and_CPP
标题[问题] 为什麽CRTP+variant还是比virtual快很多
时间Thu Jan 2 12:27:59 2020
一开始是看到这篇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都很痛苦
所以来洗耳恭听大大的教训
感恩
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 60.248.183.174 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1577939284.A.9A6.html
1F:→ Lipraxde: Vvistor 里的那个 for loop 被优化掉了,155 行的没有 01/02 21:04
3F:→ Lipraxde: ant/ <- 我觉得介绍的不错 01/02 21:07
4F:→ loveme00835: variant 做的事情就是用 type code 判断然後再转型, 01/02 23:09
5F:→ loveme00835: 而转型後实际上呼叫的函式是在编译时期就选好的, 你 01/02 23:09
6F:→ loveme00835: 可以自己用 union + type code 实作看看 01/02 23:09
7F:推 LPH66: CRTP 的「基类」并不是单一个类, 而是每个子类都有一个基类 01/03 04:51
8F:→ LPH66: 也因此虽然看起来同一段程式码被很多不同子类呼叫 01/03 04:51
9F:→ LPH66: 但因为基类是模版的关系, 每个基类是分开的 01/03 04:52
10F:→ LPH66: 这个基类在呼叫子类方法时会确定知道自己负责什麽子类 01/03 04:52
11F:→ LPH66: (藉由 CRTP 继承时给的模版参数, 所以也是编译期就确定的) 01/03 04:53
12F:→ LPH66: 因此可以省去执行所有判断子类的操作 (如 vtable 等) 01/03 04:53
13F:→ LPH66: 甚至因为子类型态确定, 呼叫当下的所需要的继承相关操作 01/03 04:56
14F:→ LPH66: 仅仅只有为求得子类实体的 downcast 而已 01/03 04:56
15F:→ LPH66: 这个 downcast 也因为是 static_cast 基本上没有判断操作 01/03 04:59
16F:→ LPH66: 简单说就是, 藉由模版把子类型态判断变成编译器的模版选择 01/03 05:01
17F:→ saladim: 请问个蠢问题...为什麽tick() function没有name hiding的 01/07 01:47
18F:→ saladim: 问题阿? 谢谢~ 01/07 01:47
19F:→ saladim: 有时会被要求compiler warning要全修... 01/07 01:54