Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: [PATCH] gdb/dwarf2: short-circuit cooked_index_entry::compare on identical strings
Date: Tue, 27 Oct 2026 16:47:36 -0400	[thread overview]
Message-ID: <20261027204739.336896-1-simon.marchi@efficios.com> (raw)

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


             reply	other threads:[~2026-10-27 20:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-27 20:47 Simon Marchi [this message]
2026-10-28 16:18 ` Tom Tromey
2026-10-28 17:21   ` Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261027204739.336896-1-simon.marchi@efficios.com \
    --to=simon.marchi@efficios.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox