gbranden pushed a commit to branch master
in repository groff.
commit 2d9cd200df13148fe2ae0ed7ff2db4cbdbe20d2d
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Jun 10 03:33:37 2026 -0500
[libgroff]: Tune `string` object allocations.
* src/libs/libgroff/string.cpp: Increase initial buffer size backing
`string` objects from 8 to 64, and stop allocating double the
requested length on initial or replacement allocations. An initial
buffer size of 64 appears to balance build time against minimization
of reallocations.
(salloc, sfree_alloc): Allocate only `len` `char` elements, not
`len * 2`, unless `len` equals zero.
(sfree_alloc): Drop now-taulogous assert(3)ion.
I instrumented `srealloc()` to report when reallocations occurred, and
timed builds with various values of `initial_string_buffer_size`.
initial size 8
--------------
real 0m32.780s
user 0m35.483s
sys 0m3.385s
realloc 535236
initial size 16
---------------
real 0m31.192s
user 0m33.949s
sys 0m3.102s
realloc 426412
initial size 32
---------------
real 0m29.430s
user 0m32.117s
sys 0m2.460s
realloc 271518
initial size 64
---------------
real 0m28.861s
user 0m31.691s
sys 0m2.384s
realloc 184568
initial size 128
----------------
real 0m30.959s
user 0m34.022s
sys 0m2.381s
realloc 75272
initial size 256
----------------
real 0m30.912s
user 0m34.149s
sys 0m2.381s
realloc 28405
We see that while, as expected, reallocations steadily decrease with
increasing "initial size", there is a local minimum in both wall-clock
and user-space time for an initial size selection of 64.
---
ChangeLog | 11 +++++++++++
src/libs/libgroff/string.cpp | 17 +++++++++++++----
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a7dcff6d7..cf1054e5a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2026-06-10 G. Branden Robinson <[email protected]>
+
+ * src/libs/libgroff/string.cpp: Increase initial buffer size
+ backing `string` objects from 8 to 64, and stop allocating
+ double the requested length on initial or replacement
+ allocations. An initial buffer size of 64 appears to balance
+ build time against minimization of reallocations.
+ (salloc, sfree_alloc): Allocate only `len` `char` elements, not
+ `len * 2`, unless `len` equals zero.
+ (sfree_alloc): Drop now-taulogous assert(3)ion.
+
2026-06-09 G. Branden Robinson <[email protected]>
* src/libs/libgroff/string.cpp: Continue refactoring to
diff --git a/src/libs/libgroff/string.cpp b/src/libs/libgroff/string.cpp
index 7f5e5a32c..862586dad 100644
--- a/src/libs/libgroff/string.cpp
+++ b/src/libs/libgroff/string.cpp
@@ -44,14 +44,20 @@ along with this program. If not, see
<http://www.gnu.org/licenses/>. */
// TODO 1: Replace all this memory management stuff with vector<char>.
// TODO 2: Replace this entire class. See Savannah #67735.
-static const size_t initial_string_buffer_size = 8;
+// An initial buffer size of 64 appears to balance build time against
+// minimization of reallocations.
+static const size_t initial_string_buffer_size = 64;
static char *salloc(size_t len, size_t *sizep)
{
char *p = 0 /* nullptr */;
- size_t amount = len * 2;
+ size_t amount = len;
if (0 == amount)
amount = initial_string_buffer_size;
+ // XXX: Add 1 as a hack to work around a problem created in
+ // src/devices/html/post-html.cpp:page::add_and_encode_char() when it
+ // is omitted. If/when we resolve that, we can assign simply `len`.
+ amount += 1;
try {
p = new char[*sizep = amount];
}
@@ -90,8 +96,9 @@ static char *sfree_alloc(char *ptr, size_t oldsz, size_t len,
return 0 /* nullptr */; // XXX: GBR: breaks invariant
}
char *p = 0 /* nullptr */;
- size_t amount = len * 2;
- assert(amount > 0);
+ size_t amount = len;
+ if (0 == amount)
+ amount = initial_string_buffer_size;
try {
p = new char[*sizep = amount];
}
@@ -116,6 +123,8 @@ static char *srealloc(char *ptr, size_t oldsz, size_t
oldlen,
return 0 /* nullptr */; // XXX: GBR: breaks invariant
}
else {
+ // If the string changes size once, assume it will change again; try
+ // to prevent excessive reallocations.
size_t amount = newlen * 2;
char *p = 0 /* nullptr */;
try {
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit