[Patch] [add changelog] reduce template instantiation depth in <variant>
Barrett Adair
barrettellisadair@gmail.com
Sun Nov 13 18:53:00 GMT 2016
On Sun, Nov 13, 2016 at 12:17 PM, Barrett Adair
<barrettellisadair@gmail.com> wrote:
> On Sun, Nov 13, 2016 at 3:08 AM, Tim Song <t.canens.cpp@gmail.com> wrote:
>> On Sat, Nov 12, 2016 at 3:48 PM, Barrett Adair
>> <barrettellisadair@gmail.com> wrote:
>>> On Sat, Nov 12, 2016 at 2:39 PM, Tim Shen <timshen@google.com> wrote:
>>>> On Sat, Nov 12, 2016 at 4:28 AM, Daniel Krügler
>>>> <daniel.kruegler@gmail.com> wrote:
>>>>> 2016-11-12 10:04 GMT+01:00 Barrett Adair <barrettellisadair@gmail.com>:
>>>
>>> Since there are no side-effects, and the metafunctions in play cannot
>>> SFINAE, I don't believe the semantics are actually affected by
>>> short-circuiting in this case.
>>
>> The issue is that the fold expression requires actually instantiating all the
>> is_meow_constructible &c. specializations (which in turn may trigger extra
>> instantiations) while __and_ only instantiates those needed for the result.
>> The extra instantiations can be expensive in terms of compile time but this,
>> of course, depends on the types involved. Some benchmarks would be nice.
>
> Here is a benchmark that I made with Metabench: http://jsbin.com/qalegikowi
>
> It appears that the effect on compile-time performance is negligible at worst.
> My original interest in contributing to <variant> was to reduce the compile-time
> complexity by number of types. It would be nice if to have a linear
> implementation, but I don't know yet whether that is possible.
>
My last benchmark didn't have any short-circuiting. Here's a benchmark where
the first type is not default-constructible, copy-constructible, or
move-constructible:
http://output.jsbin.com/himusodozu
Ruby template for the benchmark:
#include <variant>
#include <memory>
int main(int argc, char**) {
#if defined METABENCH
struct T {
int i;
std::unique_ptr<int> x;
T(int i) : i(i), x(nullptr) {}
};
<% (0..n).each do |i| %>
struct T<%= i %> { int i; std::string x; };
<% end %>
using var = std::variant< T, T<%= (0..n).to_a.join(', T') %> >;
var x(T{0});
std::visit([](auto&& v){}, x);
#endif
}
More information about the Libstdc++
mailing list