我刚看了一个更简单的
example.该表是在编译时生成的.时间可能花在std :: __ detail :: __ variant :: __ gen_vtable_impl< ...>中生成的lambdas中.出于某种原因,这些基本上呼叫访问者的lambda不会省略检查变体的实际类型.
此函数允许编译器为访问lambda的四个不同版本创建代码,内联到std :: visit内部创建的lambdas,并将指向这些lambda的指针存储在静态数组中:
double test(std::variant v1, std::variant v2) {
return std::visit([](auto a, auto b) -> double {
return a + b;
}, v1, v2);
}
这是在测试中创建的:
(...) ; load variant tags and check for bad variant
lea rax, [rcx+rax*2] ; compute index in array
mov rdx, rsi
mov rsi, rdi
lea rdi, [rsp+15]
; index into vtable with rax
call [QWORD PTR std::__detail::__variant::(... bla lambda bla ...)::S_vtable[0+rax*8]]
这是为< double,double>生成的.游客:
std::__detail::__variant::__gen_vtable_impl<:__detail::__variant::_multi_array double>, std::variant)::{lambda(auto:1, auto:2)#1}&&, std::variant&, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&)>, std::tuple, std::variant)::{lambda(auto:1, auto:2)#1}&&, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&>, std::integer_sequence >::__visit_invoke(test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&):
; whew, that is a long name :-)
; redundant checks are performed whether we are accessing variants of the correct type:
cmp BYTE PTR [rdx+8], 1
jne .L15
cmp BYTE PTR [rsi+8], 1
jne .L15
; the actual computation:
movsd xmm0, QWORD PTR [rsi]
addsd xmm0, QWORD PTR [rdx]
ret
如果探查器将这些类型检查的时间和内联访问者的时间归因于std :: __ detail :: __ variant :: __ gen_vtable_impl< ...>,而不是给你完整的800多个,我不会感到惊讶深度嵌套的lambda的字符名称.
我在这里看到的唯一通用优化潜力是省略lambda中不良变体的检查.由于lambda只通过函数指针调用,只有匹配的变量,编译器将很难静态发现检查是多余的.
decltype(auto) std::__1::__variant_detail::__visitation::__base::__dispatcher<1ul, 1ul>::__dispatch<:__1::__variant_detail::__visitation::__variant::__value_visitor double>, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&>(std::__1::__variant_detail::__visitation::__variant::__value_visitor, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&): # @"decltype(auto) std::__1::__variant_detail::__visitation::__base::__dispatcher<1ul, 1ul>::__dispatch<:__1::__variant_detail::__visitation::__variant::__value_visitor double>, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&>(std::__1::__variant_detail::__visitation::__variant::__value_visitor, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&)"
; no redundant check here
movsd xmm0, qword ptr [rsi] # xmm0 = mem[0],zero
addsd xmm0, qword ptr [rdx]
ret
也许您可以检查生产软件中实际生成的代码,以防它与我在示例中找到的代码不同.