8

Why does std::array<std::string, 65536> a = {}; take more than 17 minutes to compile with gcc using -O3 on a Core i7 9700K processor?

I've stumbled on a problem with gcc where I've empty-initialized a std::array with std::strings in the header file, rather than doing it in a dedicated constructor in a source file. The file is included in multiple places, which resulted in an near endless optimization loop. With -O0 it promptly finished, however with -O1 I've waited for over an hour on a core i7-9700K processor and gcc is still running.

I finally narrowed down the problem to the empty initialization of std::array<std::string, N> where N is some large number. A similar problem can also be seen with other non-trivial constructors for other types where the compilation time is increasing linearly with the number of elements. Like the example below.

#include <array>

struct A {
  A() : i(0) {}
  int i;
};

int main() {
  std::array<A, 65536> a = {};
  return 0;
}

In an attempt to figure this out myself I've compiled the above code to assembly code. With -O0 the assembly looks like an unrolled for loop of calls to the constructor with about 4 times the number of lines as the array size. When turning on optimization the initialization seems to be eliminated all together.

#include <array>
#include <string>

int main() {
  std::array<std::string, 65536> a = {};
  return 0;
}

When replacing the content of the array with a std::string however the compiler seems to be unable to remove the initialization of std::string even with optimization turned on.

I imagine this is part of the reason why my initial build got stuck in some endless optimization loop, but it does not explain it fully nor why clang seems to handle this so much better. Is there anyone that can shed some more light on this issue?

I have tried with a couple of gcc version ranging from gcc-6 to gcc-8. Even with gcc-4.9 it takes some time but not quite as much, clocking in on 4,5 minutes. Using clang with -stdlib=libstdc++ yields a compilation time of 0m0,120s.

Ingemar
  • 109
  • 2
  • 7
    To avoid confusion and getting closed as unclear, it seems that the question can simply be stated that why gcc is taking 100% CPU and too much time to compile this simple code with `std::array` and `std::string` when optimization is turned on. – taskinoor May 30 '19 at 10:35
  • 1
    Sorry, I'm new poster, did not anticipate the quick response and editing. To really sum it up it think the question could be re-phrased to why does "std::array a = {};" takes forever to compile with -O3 and gcc? – Ingemar May 30 '19 at 10:54
  • 3
    When you talk about a compiler, please be more specific. Which version? Which standard library (in particular, with clang, it could be libstdc++ or libc++)? The implementations of `std::string` are very different, and some bugs about initializing large arrays have been fixed. – Marc Glisse May 30 '19 at 11:10
  • 3
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80272 for instance (gcc's bugzilla is the right place, if you need to report this kind of issue and cannot find a report of the same issue). – Marc Glisse May 30 '19 at 11:23
  • 4
    Dup of https://stackoverflow.com/q/37260097/1918193 ? See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77443 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71165 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61592 – Marc Glisse May 30 '19 at 11:34
  • @MarcGlisse You are right, seems to be a bug more than anything else. Not fixed since 4.9.2 and currently on 9. Thanks! – Ingemar May 30 '19 at 11:36

0 Answers0