From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id ZDz8KQkO4Wo4ezEAWB0awg (envelope-from ) for ; Tue, 27 Oct 2026 16:48:09 -0400 Received: by simark.ca (Postfix, from userid 112) id 95B93378002; Tue, 27 Oct 2026 16:48:09 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id A613C1E007 for ; Tue, 27 Oct 2026 16:48:08 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 202DF4BA23DD for ; Tue, 27 Oct 2026 20:48:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 202DF4BA23DD Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 685FC4BA23C4 for ; Tue, 27 Oct 2026 20:47:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 685FC4BA23C4 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 685FC4BA23C4 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1793134063; cv=none; b=TvsnDMiy0kKTseiuyJ/IJLxfwOhH4OUxCNg4UsXTuCXRbq6HEknhv/0leEk+1O1yT5ADE5mwsSO2VtaRuwX2kCQZbm+IyhbWzpT9LQwtKKd3wY9ayzArtYRtvTDeA0NAP2moewDHAC5x+Njo313YKDshz13TBC5zFNW/Bez5t7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1793134063; c=relaxed/simple; bh=huqS9Fkb3g/5JkAEasIhquZC/75txI22u3RHdCPDvGg=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=HBgY3v//Lm4JqTswTesTiK+7CYY4HXHxs9NpoSuReh5r9Sj16/xXRArbHzIlEBU52NUyFIrJYWSNQOrxxGNrZooS7WhmMyb94WGeXfOe0aFWzF/Xzy1HRpBBcaTIkZg9lL9DTchCJmv4FwAw985GNQfeYNb/cRPT/IvbTDzt3/4= ARC-Authentication-Results: i=1; sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 685FC4BA23C4 Received: by simark.ca (Postfix) id 071AE1E007; Tue, 27 Oct 2026 16:47:41 -0400 (EDT) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH] gdb/dwarf2: short-circuit cooked_index_entry::compare on identical strings Date: Tue, 27 Oct 2026 16:47:36 -0400 Message-ID: <20261027204739.336896-1-simon.marchi@efficios.com> X-Mailer: git-send-email 2.56.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org When sorting the entries of a cooked index shard, at the end of cooked_index_shard::canonicalize_names, a lot of time is spent in cooked_index_entry::compare comparing names that are identical. Many entries have the exact same canonical string pointer, in which case compare walks both strings to the end only to return 0. This happens because the linker merges identical strings in .debug_str, so entries with the same name in different CUs usually have the same name pointer. For C and C++ entries, the seen_names set in canonicalize_names (which is keyed on the name pointer) makes entries with the same name pointer share the same canonical string. For other entries, the canonical string is the name itself. When asked to compare a string pointer with itself, we don't need to do any work, we know they are equal. Return 0 right away when both pointers are equal. I measured the wall and CPU time of the "file" command, with "maint set dwarf sync on" and "maint set per-command time on", with 1, 2, 4 and 8 worker threads. The CPU time adds up all threads. The numbers are the median of 5 runs. Node.js 26.12.1 (2.3 GiB of .debug_info): +---------+--------------------------+--------------------------+ | | wall (s) | CPU (s) | | threads | before after change | before after change | +---------+--------------------------+--------------------------+ | 1 | 46.94 39.09 -16.7% | 46.93 39.09 -16.7% | | 2 | 24.67 21.35 -13.4% | 45.72 39.04 -14.6% | | 4 | 14.06 12.43 -11.6% | 45.14 39.02 -13.6% | | 8 | 8.73 8.00 -8.3% | 43.72 38.44 -12.1% | +---------+--------------------------+--------------------------+ clang 23.1.4 (6.7 GiB of .debug_info, DWARF64): +---------+--------------------------+--------------------------+ | | wall (s) | CPU (s) | | threads | before after change | before after change | +---------+--------------------------+--------------------------+ | 1 | 100.25 87.14 -13.1% | 100.23 87.12 -13.1% | | 2 | 52.08 46.78 -10.2% | 98.64 87.42 -11.4% | | 4 | 28.59 26.40 -7.6% | 98.22 88.50 -9.9% | | 8 | 17.18 15.98 -7.0% | 94.99 86.39 -9.1% | +---------+--------------------------+--------------------------+ This doesn't help with split DWARF, where each .dwo file has its own string table: entries with the same name in different CUs then have different name pointers, so they rarely share a canonical string. This is with Blender 5.2, with split DWARF (-gsplit-dwarf), where the patch makes no significant difference: +---------+--------------------------+--------------------------+ | | wall (s) | CPU (s) | | threads | before after change | before after change | +---------+--------------------------+--------------------------+ | 1 | 132.79 133.80 +0.8% | 132.76 133.78 +0.8% | | 2 | 68.03 68.65 +0.9% | 128.93 129.45 +0.4% | | 4 | 35.01 35.52 +1.4% | 125.71 126.04 +0.3% | | 8 | 18.49 17.97 -2.8% | 116.31 116.05 -0.2% | +---------+--------------------------+--------------------------+ Change-Id: I7133223914304e01dc411949cbba00e847e55e2c --- gdb/dwarf2/cooked-index-entry.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gdb/dwarf2/cooked-index-entry.c b/gdb/dwarf2/cooked-index-entry.c index 44b065157b80..300e3c90af7b 100644 --- a/gdb/dwarf2/cooked-index-entry.c +++ b/gdb/dwarf2/cooked-index-entry.c @@ -62,6 +62,10 @@ cooked_index_entry::compare (const char *stra, const char *strb, return c_tolower (c); }; + /* Optimization: entries with the same name often share the same string. */ + if (stra == strb) + return 0; + unsigned char a = munge (*stra); unsigned char b = munge (*strb); base-commit: 98a43c9d844d480968b41fbe9ae6e15382ee383d -- 2.56.0