Message ID | 20220824061648.1119635-2-whh8b@obs.cr |
---|---|
State | New, archived |
Headers |
Return-Path: <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:ecc5:0:0:0:0:0 with SMTP id s5csp1280254wro; Tue, 23 Aug 2022 23:18:47 -0700 (PDT) X-Google-Smtp-Source: AA6agR5ib0qHYVqGtre3qx98vGiokSwBjQBRhkm1M2CZkGarrPcnTntRNILLwyXLfNag4qPwr3WY X-Received: by 2002:a17:907:2bf8:b0:73d:6cd3:906c with SMTP id gv56-20020a1709072bf800b0073d6cd3906cmr1827622ejc.686.1661321926949; Tue, 23 Aug 2022 23:18:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661321926; cv=none; d=google.com; s=arc-20160816; b=YiD21v8AGHdLWcq5d3KCozMXptwb6cWOMf6GyE/LEUtRjFDB6hAOsx10D8BAWTwLba xYoPb0GFKkuIBFIcththOOahdm4rvfZkpv1rLkkaY839bgOusbO7Q/AdCyA0SCfIxvmj 1KocCOfALLMXmm9Tn6cCFMr+o1ABjRuwkGuhUupEHBtzXvLqQx1VbuDWzxl00qaPT+Za uI5l0AqZcsny0EvPi6Zeu+ObmiRDRpyTHLihI3jmK1I8tHsUtFWNgH94g+XKOYHzisEy 6qs/m02I7Z6w02fWDfAetmKdjUk8U6UQ7/zuIW1IEGCgOEfAYRt1ESc/R6Vrvh7qivS9 +FBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:dmarc-filter:delivered-to; bh=UxOxuiikWxHrqz6k6C8dSil//9BkU3bPox9qIEOpTPA=; b=lqxcBQ/1aRhnTgrOc/4qWyajTwiqUq9pN18jmP69qGFzJlUvi+pimo1p+lY/2HM8t8 QrL8PDaJS2hUy+VsknGPI1MKd1NnnfUo88vC7krX9QpZWi0QtQTEXsxiuNoHNFAGJ4EY G4Q9Ipjest+oFT5KMBy5a17fh2ttxUJbWGAULRg/7CdQuORMp+c1TEKdx2s9vhbo80PJ J4xIfaIP77g4NYO01odiH7s91nIB4TdvqpzLnfkUEsWUP6oUoqjUwYHjWpQUVVvE21Ht Fr7bDo7m+24K3vmEsujMCZpdKw83SZr1bfESWqEs4CFJXjvUl3UYGtYtSCfaOdyIfRF2 8TGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@obs-cr.20210112.gappssmtp.com header.s=20210112 header.b="hA/F8sos"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id o18-20020a170906975200b0073d64fca6f7si1473161ejy.254.2022.08.23.23.18.46 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Aug 2022 23:18:46 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=fail header.i=@obs-cr.20210112.gappssmtp.com header.s=20210112 header.b="hA/F8sos"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E229A385AE41 for <ouuuleilei@gmail.com>; Wed, 24 Aug 2022 06:17:52 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x82a.google.com (mail-qt1-x82a.google.com [IPv6:2607:f8b0:4864:20::82a]) by sourceware.org (Postfix) with ESMTPS id 7EF44385703A for <gcc-patches@gcc.gnu.org>; Wed, 24 Aug 2022 06:16:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7EF44385703A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=obs.cr Authentication-Results: sourceware.org; spf=none smtp.mailfrom=obs.cr Received: by mail-qt1-x82a.google.com with SMTP id e28so12044151qts.1 for <gcc-patches@gcc.gnu.org>; Tue, 23 Aug 2022 23:16:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=obs-cr.20210112.gappssmtp.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=UxOxuiikWxHrqz6k6C8dSil//9BkU3bPox9qIEOpTPA=; b=hA/F8sosHy3Gz4HGnn+yvBbFAiIBR/1OQJN+KNfebbVAogc8BlDJTgQagi0ZnmrWqu Sf+xNvA/iPW+HvuRRUZRQ7r7N0Gh6psmI0JGm26hQsH1YYtq01f9I0Iqnc3TRqp36vCS 6ZWFY1lqZe5DokpJfOfMYd3vvW597RoTCk27FOvJ1cLHMds7ZXTRVORkP5mO79/bjcan EpfN8v45r93+onZYCkQz6o6KIB5tvQ+F5VzlfH6z1TYz1hVm5zJPndX/Ozpy2L0qypN+ rSdhzXUnocp4laoBhrCfduRKieG4lgYlxjzhtCcQZTkQG58Uy/i+1rNgTeqIfWtG0YQr sBJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=UxOxuiikWxHrqz6k6C8dSil//9BkU3bPox9qIEOpTPA=; b=0ceJ7DRjVnMPIeSWpPB/0r5AKuesILvlVlc+xFPZlO62XueFKD8RL2gbuttNvEOQft z+SL1cEecplIwmof7fpnz44Q1aKSyY8h4K9j0wAWpy4sDn5MQYMbf7ovGonoeAELdUGl M+zmiQ1ob0OUL7PM4cWlbzrn/gvgtGFxyjdW0+Y+cLD3g1C75KVmR6p+hF/YR8i455Bg myTp9Zpnw0cU7arwP63xfjKyUhD++B+Wk0jVk4VpKNm4yYPs/9jhqKlwXHD8Tfs8F+T/ rZckS82G25euxlMkuq2NH9YzVQ6TVfoVKhJGqnspZo23+tQIma5PP1LwqKKV0CKT4vHv +fcA== X-Gm-Message-State: ACgBeo0h79SmPjJbL34PYBmBi1mHal67QkqUD67aeZB3/3WjvQ0jNFqf zKfGprvUCI084TKkBa0L6RNqa48ons6ReiWu X-Received: by 2002:ac8:5f07:0:b0:344:a21c:1e02 with SMTP id x7-20020ac85f07000000b00344a21c1e02mr17938494qta.140.1661321818861; Tue, 23 Aug 2022 23:16:58 -0700 (PDT) Received: from localhost.localdomain (ip-192-24-137-251.dynamic.fuse.net. [192.24.137.251]) by smtp.gmail.com with ESMTPSA id y16-20020ac85f50000000b0031ecddf2278sm13306657qta.37.2022.08.23.23.16.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Aug 2022 23:16:58 -0700 (PDT) From: whh8b@obs.cr To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] libstdc++: Optimize operator+(string/char*, string/char*) equally Date: Wed, 24 Aug 2022 02:16:48 -0400 Message-Id: <20220824061648.1119635-2-whh8b@obs.cr> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220824061648.1119635-1-whh8b@obs.cr> References: <20220822181509.1032874-2-whh8b@obs.cr> <20220824061648.1119635-1-whh8b@obs.cr> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> Cc: Will Hawkins <whh8b@obs.cr> Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1741886282648641643?= X-GMAIL-MSGID: =?utf-8?q?1742022300574764951?= |
Series |
libstdc++: Optimize operator+(string/char*, string/char*) equally
|
|
Commit Message
Will Hawkins
Aug. 24, 2022, 6:16 a.m. UTC
From: Will Hawkins <whh8b@obs.cr> Until now operator+(char*, string) and operator+(string, char*) had different performance characteristics. The former required a single memory allocation and the latter required two. This patch makes the performance equal. libstdc++-v3/ChangeLog: * libstdc++-v3/include/bits/basic_string.h (operator+(string, char*)): Remove naive implementation. * libstdc++-v3/include/bits/basic_string.tcc (operator+(string, char*)): Add single-allocation implementation. Signed-off-by: Will Hawkins <whh8b@obs.cr> --- libstdc++-v3/include/bits/basic_string.h | 9 ++------- libstdc++-v3/include/bits/basic_string.tcc | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-)
Comments
On Wed, 24 Aug 2022 at 07:17, Will Hawkins wrote: > > Until now operator+(char*, string) and operator+(string, char*) had > different performance characteristics. The former required a single > memory allocation and the latter required two. This patch makes the > performance equal. > > libstdc++-v3/ChangeLog: There should be a blank line here. > * libstdc++-v3/include/bits/basic_string.h (operator+(string, char*)): The path should be relative to the ChangeLog, so should not include the libstdc++-v3/ directory component. You can use the git gcc-verify alias to check your commit msgs format before submitting. That runs the same checks as will be used for the server-side hook that decides whether to allow a push. See the customization script described at https://gcc.gnu.org/gitwrite.html#vendor for the alaises. Also, the overload you're changing is operator+(const string&, const char*). The distinction matters, because there is also operator+(string&&, const char*) and what you wrote looks more like that one. So I've committed it with this changelog: libstdc++-v3/ChangeLog: * include/bits/basic_string.h (operator+(const string&, const char*)): Remove naive implementation. * include/bits/basic_string.tcc (operator+(const string&, const char*)): Add single-allocation implementation. Thanks for the patch!
On Aug 24, 2022, Jonathan Wakely via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > * include/bits/basic_string.h (operator+(const string&, > const char*)): > Remove naive implementation. > * include/bits/basic_string.tcc (operator+(const string&, > const char*)): > Add single-allocation implementation. ISTM this requires the following additional tweak: diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index bfae6d902a1dd..2ec0e9d85f947 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class basic_string<C>; template S operator+(const C*, const S&); + template S operator+(const S&, const C*); template S operator+(C, const S&); template S operator+(const S&, const S&); Without this, I'm getting undefined references to this specialization in libstdc++.so, that I tracked down to a std::system_error ctor in cxx11-ios_failure.o. I got this while testing another patch that might be the reason why the template instantiation doesn't get inlined, but... we can't depend on its being inlined, can we?
On Wed, 24 Aug 2022 at 23:39, Alexandre Oliva <oliva@gnu.org> wrote: > > On Aug 24, 2022, Jonathan Wakely via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > * include/bits/basic_string.h (operator+(const string&, > > const char*)): > > Remove naive implementation. > > * include/bits/basic_string.tcc (operator+(const string&, > > const char*)): > > Add single-allocation implementation. > > ISTM this requires the following additional tweak: > > diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc > index bfae6d902a1dd..2ec0e9d85f947 100644 > --- a/libstdc++-v3/src/c++11/string-inst.cc > +++ b/libstdc++-v3/src/c++11/string-inst.cc > @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > template class basic_string<C>; > template S operator+(const C*, const S&); > + template S operator+(const S&, const C*); > template S operator+(C, const S&); > template S operator+(const S&, const S&); > > > Without this, I'm getting undefined references to this specialization in > libstdc++.so, that I tracked down to a std::system_error ctor in > cxx11-ios_failure.o. I got this while testing another patch that might > be the reason why the template instantiation doesn't get inlined, but... > we can't depend on its being inlined, can we? Right. But adding that will cause another symbol to be exported, probably with the wrong symbol version. To fix https://gcc.gnu.org/PR106735 I'm just going to revert it for now, and revisit in the morning.
On Wed, 24 Aug 2022 at 23:47, Jonathan Wakely <jwakely@redhat.com> wrote: > > On Wed, 24 Aug 2022 at 23:39, Alexandre Oliva <oliva@gnu.org> wrote: > > > > On Aug 24, 2022, Jonathan Wakely via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > > * include/bits/basic_string.h (operator+(const string&, > > > const char*)): > > > Remove naive implementation. > > > * include/bits/basic_string.tcc (operator+(const string&, > > > const char*)): > > > Add single-allocation implementation. > > > > ISTM this requires the following additional tweak: > > > > diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc > > index bfae6d902a1dd..2ec0e9d85f947 100644 > > --- a/libstdc++-v3/src/c++11/string-inst.cc > > +++ b/libstdc++-v3/src/c++11/string-inst.cc > > @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > > template class basic_string<C>; > > template S operator+(const C*, const S&); > > + template S operator+(const S&, const C*); > > template S operator+(C, const S&); > > template S operator+(const S&, const S&); > > > > > > Without this, I'm getting undefined references to this specialization in > > libstdc++.so, that I tracked down to a std::system_error ctor in > > cxx11-ios_failure.o. I got this while testing another patch that might > > be the reason why the template instantiation doesn't get inlined, but... > > we can't depend on its being inlined, can we? > > Right. But adding that will cause another symbol to be exported, > probably with the wrong symbol version. Oh, but those symbols aren't exported ... they're just needed because we compile with -fno-implicit-templatesand other symbols in libstdc++.so require them. So that probably is the right fix. I have another change for operator+ in mind now anyway, which optimizes operator(const string&, char) the same way, and removes the duplication in those five operator+ overloads. > > To fix https://gcc.gnu.org/PR106735 I'm just going to revert it for > now, and revisit in the morning.
On Wed, Aug 24, 2022 at 7:03 PM Jonathan Wakely <jwakely@redhat.com> wrote: > > On Wed, 24 Aug 2022 at 23:47, Jonathan Wakely <jwakely@redhat.com> wrote: > > > > On Wed, 24 Aug 2022 at 23:39, Alexandre Oliva <oliva@gnu.org> wrote: > > > > > > On Aug 24, 2022, Jonathan Wakely via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > > > > * include/bits/basic_string.h (operator+(const string&, > > > > const char*)): > > > > Remove naive implementation. > > > > * include/bits/basic_string.tcc (operator+(const string&, > > > > const char*)): > > > > Add single-allocation implementation. > > > > > > ISTM this requires the following additional tweak: > > > > > > diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc > > > index bfae6d902a1dd..2ec0e9d85f947 100644 > > > --- a/libstdc++-v3/src/c++11/string-inst.cc > > > +++ b/libstdc++-v3/src/c++11/string-inst.cc > > > @@ -58,6 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > > > > > template class basic_string<C>; > > > template S operator+(const C*, const S&); > > > + template S operator+(const S&, const C*); > > > template S operator+(C, const S&); > > > template S operator+(const S&, const S&); > > > I realize that I should have noticed that asymmetry as well. Sorry! > > > > > > Without this, I'm getting undefined references to this specialization in > > > libstdc++.so, that I tracked down to a std::system_error ctor in > > > cxx11-ios_failure.o. I got this while testing another patch that might > > > be the reason why the template instantiation doesn't get inlined, but... > > > we can't depend on its being inlined, can we? > > > > Right. But adding that will cause another symbol to be exported, > > probably with the wrong symbol version. > > Oh, but those symbols aren't exported ... they're just needed because > we compile with -fno-implicit-templatesand other symbols in > libstdc++.so require them. > > So that probably is the right fix. I have another change for operator+ > in mind now anyway, which optimizes operator(const string&, char) the > same way, and removes the duplication in those five operator+ > overloads. Let me know if/how I can help. Will > > > > > To fix https://gcc.gnu.org/PR106735 I'm just going to revert it for > > now, and revisit in the morning. >
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index b04fba95678..fa6738925bb 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -3521,14 +3521,9 @@ _GLIBCXX_END_NAMESPACE_CXX11 */ template<typename _CharT, typename _Traits, typename _Alloc> _GLIBCXX20_CONSTEXPR - inline basic_string<_CharT, _Traits, _Alloc> + basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, - const _CharT* __rhs) - { - basic_string<_CharT, _Traits, _Alloc> __str(__lhs); - __str.append(__rhs); - return __str; - } + const _CharT* __rhs); /** * @brief Concatenate string and character. diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 4563c61429a..95ba8e503e9 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -640,6 +640,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __str; } + template<typename _CharT, typename _Traits, typename _Alloc> + _GLIBCXX20_CONSTEXPR + basic_string<_CharT, _Traits, _Alloc> + operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, + const _CharT* __rhs) + { + __glibcxx_requires_string(__rhs); + typedef basic_string<_CharT, _Traits, _Alloc> __string_type; + typedef typename __string_type::size_type __size_type; + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template + rebind<_CharT>::other _Char_alloc_type; + typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; + const __size_type __len = _Traits::length(__rhs); + __string_type __str(_Alloc_traits::_S_select_on_copy( + __lhs.get_allocator())); + __str.reserve(__len + __lhs.size()); + __str.append(__lhs); + __str.append(__rhs, __len); + return __str; + } + template<typename _CharT, typename _Traits, typename _Alloc> _GLIBCXX_STRING_CONSTEXPR typename basic_string<_CharT, _Traits, _Alloc>::size_type