gbranden pushed a commit to branch master
in repository groff.

commit c17c329f34f8fc3e00139115bd66953238447580
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Oct 20 15:34:18 2025 -0500

    [gropdf]: Fix Savannah #67602 (hella bad perf).
    
    * tmac/pdf.tmac: Fix performance regression in PDF bookmark lookups,
      using O(1) lookup method instead of one that is formally O(n) but
      probably O(n^2) in practice as the number of bookmarks in a document
      increases.
    
      (pdf:lookup): Finagle a constant-time lookup for PDF bookmarks, which
      are stored as string names.  Drop linear lookup by bookmark number,
      comparing value of each numbered bookmark's "tag" to the given macro
      argument.  Instead, assign value of first argument to new string
      `pdf:lookup-target`.  Use GNU troff's `als` aliasing facility to make
      new string `pdf:lookup-result` an alias of `pdf:lookup-target`.
      Remove `pdf:lookup-target` before returning, leaving
      `pdf:lookup-result` defined for benefit of callers.
    
      (pdf*href): Assign value of `pdf:lookup-result` string instead of
      vanished `pdf:lookup-value` to string `PDFHREF.DESC`.
    
    Fixes <https://savannah.gnu.org/bugs/?67602>.  Thanks to Deri James for
    the report; he noted a major regression in PDF production time with the
    non-constant lookup time when generating Alex Colomar's collected Linux
    man-pages document.  For me, this takes generation time down from about
    40 minutes to about 30 seconds.  Problem introduced by me in commit
    aa43ffcfb8, 16 March 2024, but not immediately exposed--that took some
    more work on PDF bookmark hyperlinking.
---
 ChangeLog     | 27 +++++++++++++++++++++++++++
 tmac/pdf.tmac | 27 ++++++++++-----------------
 2 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2bb964fd9..85c8c6ce3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2025-10-14  G. Branden Robinson <[email protected]>
+
+       * tmac/pdf.tmac: Fix performance regression in PDF bookmark
+       lookups, using O(1) lookup method instead of one that is
+       formally O(n) but probably O(n^2) in practice as the number of
+       bookmarks in a document increases.
+       (pdf:lookup): Finagle a constant-time lookup for PDF bookmarks,
+       which are stored as string names.  Drop linear lookup by
+       bookmark number, comparing value of each numbered bookmark's
+       "tag" to the given macro argument.  Instead, assign value of
+       first argument to new string `pdf:lookup-target`.  Use GNU
+       troff's `als` aliasing facility to make new string
+       `pdf:lookup-result` an alias of `pdf:lookup-target`.  Remove
+       `pdf:lookup-target` before returning, leaving
+       `pdf:lookup-result` defined for benefit of callers.
+       (pdf*href): Assign value of `pdf:lookup-result` string instead
+       of vanished `pdf:lookup-value` to string `PDFHREF.DESC`.
+
+       Fixes <https://savannah.gnu.org/bugs/?67602>.  Thanks to Deri
+       James for the report; he noted a major regression in PDF
+       production time with the non-constant lookup time when
+       generating Alex Colomar's collected Linux man-pages document.
+       For me, this takes generation time down from about 40 minutes to
+       about 30 seconds.  Problem introduced by me in commit
+       aa43ffcfb8, 16 March 2024, but not immediately exposed--that
+       took some more work on PDF bookmark hyperlinking.
+
 2025-10-14  G. Branden Robinson <[email protected]>
 
        * font/devpdf/Foundry.in:
diff --git a/tmac/pdf.tmac b/tmac/pdf.tmac
index f007c3d00..4f0ab9b25 100644
--- a/tmac/pdf.tmac
+++ b/tmac/pdf.tmac
@@ -187,24 +187,17 @@ am solely responsible for any bugs I may have introduced 
into this file.
 .\"
 .nr PDFOUTLINE.FOLDLEVEL 10000
 .\"
-.\" Search defined bookmarks for a tag matching $1.  This gets around
-.\" problems with *roff escape sequences embedded in identifiers (which
-.\" is not allowed by the language syntax), and the need to tediously
-.\" scrub the strings of them (and throw diagnostics in the user's face
-.\" if we don't do a good enough job) at the expense of an O(n) search
-.\" every time we reference a bookmark instead of an O(1) one.
+.\" Search defined bookmarks for a tag matching $1.  This approach gets
+.\" around problems with *roff escape sequences embedded in identifiers
+.\" (which is not allowed by the language syntax), and the need to
+.\" tediously scrub the strings of them (and throw diagnostics in the
+.\" user's face if we don't do a good enough job).
 .\"
 .de pdf:lookup
-.nr pdf:index 0 1
-.ds pdf:lookup-result \" empty
-.ds pdf:lookup-value  \" empty
-.while d pdf:bm\\n+[pdf:index].tag \{\
-.   if '\\$1'\\*[pdf:bm\\n[pdf:index].tag]' \{\
-.      ds pdf:lookup-result \\*[pdf:bm\\n[pdf:index].tag]\"
-.      ds pdf:lookup-value \\*[pdf:bm\\n[pdf:index].val]\"
-.      break
-.      \}
-.   \}
+.rm pdf:lookup-result
+.ds pdf:lookup-target \\$1
+.als pdf:lookup-result pdf:lookup-target
+.rm pdf:lookup-target
 ..
 .
 .\" The actual job of creating an outline reference
@@ -719,7 +712,7 @@ with '-A' option
 .   el \{\
 .      ds PDFHREF.DESC Unknown
 .      pdf:lookup \\*[pdf:href-D]
-.      if !'\\*[pdf:lookup-result]'' .ds PDFHREF.DESC \\*[pdf:lookup-value]
+.      if !'\\*[pdf:lookup-result]'' .ds PDFHREF.DESC \\*[pdf:lookup-result]
 .      \}
 .   \" Apply border and colour specifications to the PDFMARK string
 .   \" definition, as required.

_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to