Skip to content

Conversion operation slow to compile for longer lists N>=12 #2

@albi-k

Description

@albi-k

Hi,
Thank you for a really neat and concise library.

I ran into an issue with compilation time when using the conversion to/to_tuple operator. The compilation time seems to grow exponentially and is noticed for lists beyond just a few elements.

I want to document that here and the workarounds I tried to inform anyone else running into the same thing but also to hopefully resolve the long compilation time issue without needing to resort to workarounds.

The problem code:

#include <string>

//List of 13 types
using types = tl::type_list<int, bool, long, int, bool, char, size_t, long, std::string, size_t, char, std::string, bool>;

//1. Using tl::to<>   (12s)
using tup = types::to_tuple;

At 13 elements this takes over 10s to compile. An extra element and it's 20.

Workaround 1:

//2. Using specialization (< 1s)
//Need to write one of these for each target type
template <typename... Args>
struct wrap_as_tuple;

template <typename... Args>
struct wrap_as_tuple<tl::type_list<Args...>>
{
    using type = std::tuple<Args...>;
};

template <typename... Args>
using wrap_as_tuple_t = typename wrap_as_tuple<Args...>::type;

using tup = wrap_as_tuple_t<types>;

This workaround is fast but it is not generic enough: you have to write one of these for every target type.

Workaround 2:

//3. Using this external helper template (< 1s)
//Works similarly to tl::to<> in terms of using a variadic template template parameters
//however is more general and somehow compiles faster
template<template<typename...> class, typename>
struct _apply_tmpl_args_of;

template<template<typename...> class OtherTmpl, template<typename...> class Tmpl, typename... Args>
struct _apply_tmpl_args_of<OtherTmpl, Tmpl<Args...>> 
{
    using type = OtherTmpl<Args...>;
};

template<template<typename...> class OtherTmpl, typename T>
using apply_tmpl_args_of_t = typename _apply_tmpl_args_of<OtherTmpl, T>::type;

using tup = apply_tmpl_args_of_t<std::tuple, types>;

This workaround is generic and also performs fast. What baffles me is that it is not fundamentally that different to tl::to<> in the sense that both use variadic template template parameters.

Any ideas on how to<> can integrate the above idea and preserve compilation speed? MyTypeList::to<> is nicer to write than the above.

Link with examples above:
https://gcc.godbolt.org/z/6hYqc7Mv5

Thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions