[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 --- Comment #7 from Jonathan Wakely --- For some value of 1024
[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 --- Comment #6 from Jonathan Wakely --- The bottom line, however, is that this use of std::to_array is not really reasonable. You're asking the compiler to create a variadic pack of 262144 integers, and then create a pack expansion for std::array{arr[i]...} where i... has 262144 elements in the pack. That's going to be insanely large. Maybe we can do this though: template [[nodiscard]] constexpr array, _Nm> to_array(_Tp (&__a)[_Nm]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { static_assert(!is_array_v<_Tp>); static_assert(is_constructible_v<_Tp, _Tp&>); if constexpr (_Nm > 1024 && is_trivially_default_constructible_v<_Tp> && is_trivially_assignable_v<_Tp&, _Tp&>) { array<_Tp, _Nm> __arr; for (size_t __i = 0; __i < _Nm; ++i) __arr[__i] = __a[__i]; return __arr; } else if constexpr (is_constructible_v<_Tp, _Tp&>) return [&__a](index_sequence<_Idx...>) { return array, _Nm>{{ __a[_Idx]... }}; }(make_index_sequence<_Nm>{}); __builtin_unreachable(); // FIXME: see PR c++/91388 }
[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 --- Comment #5 from Jonathan Wakely --- It's hard to bisect where it got slower between 10 and 11, and between 11 and 12, because for --enable-checking builds the extra assertions slow everything down and the difference between "fast with slow assertions" and "slow with slow assertions" is much less significant than "fast" and "slow".
[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 --- Comment #4 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #2) > The "obvious" alternative impl using a lambda expression is even slower: Actually for GCC 13 it's faster: $ time ~/gcc/13/bin/g++ 110167.cc -c -O3 real0m9.422s user0m9.232s sys 0m0.170s $ time ~/gcc/13/bin/g++ 110167.cc -c -O3 -DUSE_LAMBDA real0m6.403s user0m6.342s sys 0m0.048s So that's nice.
[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 --- Comment #3 from Jonathan Wakely --- $ time ~/gcc/9/bin/g++ 110167.cc -c -O3 real0m5.568s user0m5.497s sys 0m0.035s $ time ~/gcc/10/bin/g++ 110167.cc -c -O3 real0m5.393s user0m5.355s sys 0m0.028s $ time ~/gcc/11/bin/g++ 110167.cc -c -O3 real0m10.543s user0m10.205s sys 0m0.317s $ time ~/gcc/12/bin/g++ 110167.cc -c -O3 real0m14.042s user0m13.747s sys 0m0.270s $ time ~/gcc/13/bin/g++ 110167.cc -c -O3 real0m9.422s user0m9.232s sys 0m0.170s
[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 --- Comment #2 from Jonathan Wakely --- The "obvious" alternative impl using a lambda expression is even slower: template struct array { int data[N]; }; template struct seq { }; #ifndef USE_LAMBDA template array to_array_impl(int ()[sizeof...(Idx)], seq) { return {{a[Idx]...}}; } #endif template array to_array(int ()[N]) { #ifndef USE_LAMBDA return to_array_impl(a, seq<__integer_pack(N)...>{}); #else return [](seq) { return array{{ a[I]... }}; }(seq<__integer_pack(N)...>{}); #endif } constexpr int S = 2000; int f[S]; array g(void) { return to_array(f); }
[Bug c++/110167] excessive compile time when optimizing std::to_array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110167 Jonathan Wakely changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2023-06-08 Keywords||compile-time-hog Status|UNCONFIRMED |NEW Component|libstdc++ |c++ --- Comment #1 from Jonathan Wakely --- Reduced: template struct array { int data[N]; }; template struct seq { }; template array to_array_impl(int ()[sizeof...(Idx)], seq) { return {{a[Idx]...}}; } template array to_array(int ()[N]) { return to_array_impl(a, seq<__integer_pack(N)...>{}); } int f[262144]; auto g(void) { return to_array(f); }