Skip to content

C-string functions: behaviour and performance - #80

Merged
synesissoftware merged 27 commits into
synesissoftware:devfrom
mwsis:mem-fns
Oct 27, 2026
Merged

synesissoftware merged 27 commits into
synesissoftware:devfrom
mwsis:mem-fns

Conversation

@mwsis

@mwsis mwsis commented Oct 25, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

mwsis and others added 23 commits October 22, 2026 16:18
Hoist the per-section warmup, loop, and iteration counts to one shared
schedule of 2 warmups, 1 loop, and 1,000,000 iterations. The previous
4 x 100 x 1,000,000 schedule was repeated in every section and took about
ten minutes.
Cover strnchr, strnicmp, strnistrn, strnpbrkn, strnrchr, and strnstrn,
plus each wchar analogue, with C and C++ programs. strnistrn stays on
the current inner loop, so the first-character false-match cases fail;
The inner loops of stlsoft_C_strnistrn() and stlsoft_C_wcsnistrn() compared
*s1 with *s2 on every index, so a first-character hit was treated as a full
match. Index the pair, and fold the wide form with towupper.
Store high-bit c_string test bytes in unsigned char so MSVC does not warn
C4310. Keep auto_buffer's deallocate out of line on GCC 12+, and suppress
-Wfree-nonheap-object, which mis-reports a delete of the internal buffer
from simple_string's unit test.
A 108-character path fills Linux sun_path and is not NUL-terminated.
TEST_MS_EQ then read past the array. Use TEST_MS_EQ_N when the path
length is the capacity, as the 104-character case already does.
Replace per-byte toupper and towupper on the strnistrn hot path with an
unsigned-char ASCII fold. The needle's first unit is folded once.
wchar_t units outside 0-127 still use towupper. Non-ASCII bytes are no
longer folded by the current locale.
Replace per-byte toupper and towupper on the strnicmp mismatch path with
an unsigned-char ASCII fold. Equal bytes still skip the fold. wchar_t units
outside 0-127 still use towupper.
Call memchr and wmemchr when the search value is in 0-127. Values outside
that range stay on the scalar loop, so a high byte still compares as a
promoted char.
Find the first needle byte with memchr over the positions that can still
hold the needle, then memcmp the remaining bytes. A partial hit resumes one
past that byte. wchar_t uses wmemchr and wmemcmp. An empty needle still
returns the haystack.
* 1.11.2 version elements

* fix(stlsoft): silence GCC 12+ free-nonheap warning in auto_buffer

Mark `deallocate_()` `STLSOFT_NOINLINE` on GCC 12+ so `operator delete`
stays out of the inlined destructor, and suppress `-Wfree-nonheap-object`
around the external-buffer `delete`, which GCC misattributes to the
internal buffer.

* test(stlsoft): compare a full sun_path with a counted string

A 108-character path fills Linux sun_path and is not NUL-terminated.
TEST_MS_EQ then read past the array. Use TEST_MS_EQ_N when the path
length is the capacity, as the 104-character case already does.

---------

Co-authored-by: Matt Wilson <matthew.wilson.synesis@gmail.com>
* refactor(unit-tests): applying xTests' null macros

* 1.11.2-alpha1

* `auto_buffer` extraneous warning (synesissoftware#74)

* 1.11.2 version elements

* fix(stlsoft): silence GCC 12+ free-nonheap warning in auto_buffer

Mark `deallocate_()` `STLSOFT_NOINLINE` on GCC 12+ so `operator delete`
stays out of the inlined destructor, and suppress `-Wfree-nonheap-object`
around the external-buffer `delete`, which GCC misattributes to the
internal buffer.

* test(stlsoft): compare a full sun_path with a counted string

A 108-character path fills Linux sun_path and is not NUL-terminated.
TEST_MS_EQ then read past the array. Use TEST_MS_EQ_N when the path
length is the capacity, as the 104-character case already does.

---------

Co-authored-by: Matt Wilson <matthew.wilson.synesis@gmail.com>

---------

Co-authored-by: synesissoftware <matthew@synesis.com.au>
…roughout the repo (synesissoftware#75)

* `auto_buffer` extraneous warning (synesissoftware#74)

* 1.11.2 version elements

* fix(stlsoft): silence GCC 12+ free-nonheap warning in auto_buffer

Mark `deallocate_()` `STLSOFT_NOINLINE` on GCC 12+ so `operator delete`
stays out of the inlined destructor, and suppress `-Wfree-nonheap-object`
around the external-buffer `delete`, which GCC misattributes to the
internal buffer.

* test(stlsoft): compare a full sun_path with a counted string

A 108-character path fills Linux sun_path and is not NUL-terminated.
TEST_MS_EQ then read past the array. Use TEST_MS_EQ_N when the path
length is the capacity, as the 104-character case already does.

---------

Co-authored-by: Matt Wilson <matthew.wilson.synesis@gmail.com>

* chore(nomenclature): standardise use of alpha/beta/rc nomenclature throughout the repo

---------

Co-authored-by: Matt Wilson <matthew.wilson.synesis@gmail.com>
* test(stlsoft): add exhaustive c_string unit tests

Cover strnchr, strnicmp, strnistrn, strnpbrkn, strnrchr, and strnstrn,
plus each wchar analogue, with C and C++ programs. strnistrn stays on
the current inner loop, so the first-character false-match cases fail;

* fix(stlsoft): compare each strnistrn character, not only the first

The inner loops of stlsoft_C_strnistrn() and stlsoft_C_wcsnistrn() compared
*s1 with *s2 on every index, so a first-character hit was treated as a full
match. Index the pair, and fold the wide form with towupper.

* chore(automated tests): namespace commenting

* fix(stlsoft): quiet MSVC C4310

Store high-bit c_string test bytes in unsigned char so MSVC does not warn
C4310.

---------

Co-authored-by: Matt Wilson <matthew.wilson.synesis@gmail.com>
@mwsis
mwsis requested a review from synesissoftware October 25, 2026 09:23
@mwsis mwsis self-assigned this Oct 25, 2026
@synesissoftware
synesissoftware changed the base branch from dev to master October 26, 2026 22:56
@mwsis
mwsis changed the base branch from master to dev October 27, 2026 05:12
Add one table per helper covering the local Mac and the six CI cells.
Paired cells are baseline time divided by the STLSoft time, so a value
above 1 means the STLSoft function was faster. strnistrn stays as total
nanoseconds because it has no paired baseline.
@mwsis
mwsis requested review from GarthJL1965 and Hazzoz October 27, 2026 07:38
@synesissoftware
synesissoftware merged commit 59fb562 into synesissoftware:dev Oct 27, 2026
68 checks passed
@mwsis
mwsis deleted the mem-fns branch October 27, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants