From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il1-x12d.google.com (mail-il1-x12d.google.com [IPv6:2607:f8b0:4864:20::12d]) by sourceware.org (Postfix) with ESMTPS id 0C7923844044 for ; Fri, 10 Jul 2020 20:25:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0C7923844044 Received: by mail-il1-x12d.google.com with SMTP id t27so6142562ill.9 for ; Fri, 10 Jul 2020 13:25:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=YR5aU01o/kDzLbB0O84MDrLccN6NdsrDkA0dqCm66bg=; b=hMkPmDvsQIiVP+8fahZ2u8aHvgbn0B1ciGZz3UsnG7fL5rXFIG7WSgUwSu09+cN0w2 yF1ZapM4bNt8fOnsNkr++Qa7NHhctTRWG9zTO7Y18GPT8ciLcO8Mw5C6LqA5KTw3PRat 3lJmYc4ym1Kub1oBPBRk8Ve44GZH3V3xGmrS19ijxk4eEjRPWkI3c3eeScjc8T5b2izJ 7oJgaH0VaOSgvl3I8haUW1mqSzMbvtaAYlkn8HdQ6oPsEMI+gp9rm7M7pMBJ9AaSkkwF GUcPU4gFSo3Hc9zx83oL+x7foKjsnCKB2xM1i6y+JG1+iKPdmyFHP3vXYcOSMW3a0d7C DrVA== X-Gm-Message-State: AOAM532P304FIL451QBUdWWbyBY4ctI7UaSE6DbH1DZ/93hAGH2TOb6b FhuFpMseHW6AKpgKusoON4kePiuPsXLZzG/j0LU= X-Google-Smtp-Source: ABdhPJxSyzikMjMRQH6ZJtzBr7bzCPzTOuSrgSvH4pO6gywXTyAekIMiDbfm8yJDonPIJjQQmF4wJZSPdrJwlZsjYgk= X-Received: by 2002:a92:52:: with SMTP id 79mr49281290ila.59.1594412711500; Fri, 10 Jul 2020 13:25:11 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Jonathan Wakely Date: Fri, 10 Jul 2020 21:25:00 +0100 Message-ID: Subject: Re: stdc++ issue: extremely long compile time with large number of string literals To: Mandeep Sandhu Cc: gcc-help Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Jul 2020 20:25:14 -0000 On Fri, 10 Jul 2020 at 20:36, Mandeep Sandhu wrote: > > > Please reply to the mailing list, not just to me. > > Sorry, this must've happened by mistake (I almost always to a > Reply-all when replying to messages from mailing lists) > > > > > > > Thanks for the explanation. Still surprising that the performance > > > degraded so much! Will this destruction loop run in quadratic time? > > > > No, only the compilation time is quadratic. The runtime performance > > should be linear in the number of elements. > > Right, my question was poorly worded. When I said "Will this > destruction loop run in quadratic time", I meant the time the compiler > takes to create the exception handling code for N-1 elements. > > > I don't think you mean "raw string literals", do you? > > "Raw string" has a very specific meaning: > > https://en.cppreference.com/w/cpp/language/string_literal > > You're right, no I did not mean the one mentioned above (with the R > prefix). Whats the correct term for a const char* (which is what I > meant)? Just a string literal. A raw string literal is the special kind with the R prefix. > > > > Your email subject says "large number of string literals" but what > > your code actually does is create a large > > std::initializer_list, which is not the same. > > > > If you do create string literals and then construct from that it > > compiles much faster. This is similar to your original: > > Just to be sure I follow you, the following invokes > std::initializer_list > std::unordered_set s ({"a", "b", ...}); // this is what I > reported the issue with > > but this does not? > std::unordered_set s {"a", "b", ...}; (and is faster?) They're the same. > > > > $ printf '#include \n#include > > \nstd::unordered_set s{\n' > init.C ; seq > > --format='"%.0f",' 1 50000 >> init.C ; printf '};\n' >> init.C > > $ time g++ init.C -c > > > > real 1m57.054s > > user 1m55.370s > > sys 0m1.117s > > On my machine, this too compiles forever (its been compiling for 20+ > mins. I'm running on macbook with quad-core i7 & 8GB RAM) Yes, that's the slow version. > > > > This creates an array of string literals and then constructs from that: > > > > $ printf '#include \n#include > > \nstd::unordered_set make_set() {\nconst char* > > arr[] = {\n' > init2.C ; seq --format='"%.0f",' 1 50000 >> init2.C ; > > printf '};\nreturn std::unordered_set{std::begin(arr), > > std::end(arr)};\n}\nauto s = make_set();\n' >> init2.C > > tmp$ time g++ init2.C -c > > > > real 0m0.662s > > user 0m0.591s > > sys 0m0.069s > > > > As you can see, this is almost instant. > > Indeed it is! Although I have no idea why. Won't this form also > require the same kind of exception handling code? when its iterating > "arr", won't the compiler have to still ensure that prior objects are > deleted if constructing a string obj from the current element fails? > > Or maybe the slowness comes from the way initializer_list specifically > handles this? It's the array of std::string that the std::initializer_list refers to that causes the problem. In the faster code there is no array of std::string, it's an array of const char*. Initializing a const char* can't throw an exception, and destroying it is a no-op, so there's no exception handling code needed for the array.