From 6a455aab6ef2c6efd6703cfa9319268b503a8e14 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 12 Jul 2023 17:33:14 +0200 Subject: [PATCH] mbiter, mbuiter: Small optimization. * lib/mbiter.h: Optimize away the in_shift field when the module 'mbrtoc32-regular' is in use. * lib/mbuiter.h: Likewise. --- ChangeLog | 7 +++++++ lib/mbiter.h | 34 +++++++++++++++++++++++++++++++++- lib/mbuiter.h | 25 ++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 324be4a6ab..e88f8572d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-07-12 Bruno Haible + + mbiter, mbuiter: Small optimization. + * lib/mbiter.h: Optimize away the in_shift field when the module + 'mbrtoc32-regular' is in use. + * lib/mbuiter.h: Likewise. + 2023-07-12 Gavin Smith gendocs: support chapter- and section-level split diff --git a/lib/mbiter.h b/lib/mbiter.h index 179338a856..e5d7241036 100644 --- a/lib/mbiter.h +++ b/lib/mbiter.h @@ -102,8 +102,15 @@ _GL_INLINE_HEADER_BEGIN struct mbiter_multi { const char *limit; /* pointer to end of string */ + #if !GNULIB_MBRTOC32_REGULAR bool in_shift; /* true if next byte may not be interpreted as ASCII */ + /* If GNULIB_MBRTOC32_REGULAR, it is always false, + so optimize it away. */ + #endif mbstate_t state; /* if in_shift: current shift state */ + /* If GNULIB_MBRTOC32_REGULAR, it is in an initial state + before and after every mbiter_multi_next invocation. + */ bool next_done; /* true if mbi_avail has already filled the following */ struct mbchar cur; /* the current character: const char *cur.ptr pointer to current character @@ -119,8 +126,10 @@ mbiter_multi_next (struct mbiter_multi *iter) { if (iter->next_done) return; + #if !GNULIB_MBRTOC32_REGULAR if (iter->in_shift) goto with_shift; + #endif /* Handle most ASCII characters quickly, without calling mbrtowc(). */ if (is_basic (*iter->cur.ptr)) { @@ -137,8 +146,10 @@ mbiter_multi_next (struct mbiter_multi *iter) else { assert (mbsinit (&iter->state)); + #if !GNULIB_MBRTOC32_REGULAR iter->in_shift = true; with_shift: + #endif iter->cur.bytes = mbrtoc32 (&iter->cur.wc, iter->cur.ptr, iter->limit - iter->cur.ptr, &iter->state); if (iter->cur.bytes == (size_t) -1) @@ -147,7 +158,9 @@ mbiter_multi_next (struct mbiter_multi *iter) iter->cur.bytes = 1; iter->cur.wc_valid = false; /* Allow the next invocation to continue from a sane state. */ + #if !GNULIB_MBRTOC32_REGULAR iter->in_shift = false; + #endif memset (&iter->state, '\0', sizeof (mbstate_t)); } else if (iter->cur.bytes == (size_t) -2) @@ -155,8 +168,10 @@ mbiter_multi_next (struct mbiter_multi *iter) /* An incomplete multibyte character at the end. */ iter->cur.bytes = iter->limit - iter->cur.ptr; iter->cur.wc_valid = false; + #if !GNULIB_MBRTOC32_REGULAR /* Cause the next mbi_avail invocation to return false. */ iter->in_shift = false; + #endif /* Whether to reset iter->state or not is not important; the string end is reached anyway. */ } @@ -181,8 +196,8 @@ mbiter_multi_next (struct mbiter_multi *iter) characters more quickly. */ #if !GNULIB_MBRTOC32_REGULAR if (mbsinit (&iter->state)) - #endif iter->in_shift = false; + #endif } } iter->next_done = true; @@ -199,9 +214,11 @@ MBITER_INLINE void mbiter_multi_copy (struct mbiter_multi *new_iter, const struct mbiter_multi *old_iter) { new_iter->limit = old_iter->limit; + #if !GNULIB_MBRTOC32_REGULAR if ((new_iter->in_shift = old_iter->in_shift)) memcpy (&new_iter->state, &old_iter->state, sizeof (mbstate_t)); else + #endif memset (&new_iter->state, 0, sizeof (mbstate_t)); new_iter->next_done = old_iter->next_done; mb_copy (&new_iter->cur, &old_iter->cur); @@ -209,13 +226,28 @@ mbiter_multi_copy (struct mbiter_multi *new_iter, const struct mbiter_multi *old /* Iteration macros. */ typedef struct mbiter_multi mbi_iterator_t; +#if !GNULIB_MBRTOC32_REGULAR #define mbi_init(iter, startptr, length) \ ((iter).cur.ptr = (startptr), (iter).limit = (iter).cur.ptr + (length), \ (iter).in_shift = false, memset (&(iter).state, '\0', sizeof (mbstate_t)), \ (iter).next_done = false) +#else +/* Optimized: no in_shift. */ +#define mbi_init(iter, startptr, length) \ + ((iter).cur.ptr = (startptr), (iter).limit = (iter).cur.ptr + (length), \ + memset (&(iter).state, '\0', sizeof (mbstate_t)), \ + (iter).next_done = false) +#endif +#if !GNULIB_MBRTOC32_REGULAR #define mbi_avail(iter) \ (((iter).cur.ptr < (iter).limit || (iter).in_shift) \ && (mbiter_multi_next (&(iter)), true)) +#else +/* Optimized: no in_shift. */ +#define mbi_avail(iter) \ + ((iter).cur.ptr < (iter).limit \ + && (mbiter_multi_next (&(iter)), true)) +#endif #define mbi_advance(iter) \ ((iter).cur.ptr += (iter).cur.bytes, (iter).next_done = false) diff --git a/lib/mbuiter.h b/lib/mbuiter.h index 7cadb8b402..e78ffa46ae 100644 --- a/lib/mbuiter.h +++ b/lib/mbuiter.h @@ -110,8 +110,15 @@ _GL_INLINE_HEADER_BEGIN struct mbuiter_multi { + #if !GNULIB_MBRTOC32_REGULAR bool in_shift; /* true if next byte may not be interpreted as ASCII */ + /* If GNULIB_MBRTOC32_REGULAR, it is always false, + so optimize it away. */ + #endif mbstate_t state; /* if in_shift: current shift state */ + /* If GNULIB_MBRTOC32_REGULAR, it is in an initial state + before and after every mbuiter_multi_next invocation. + */ bool next_done; /* true if mbui_avail has already filled the following */ struct mbchar cur; /* the current character: const char *cur.ptr pointer to current character @@ -127,8 +134,10 @@ mbuiter_multi_next (struct mbuiter_multi *iter) { if (iter->next_done) return; + #if !GNULIB_MBRTOC32_REGULAR if (iter->in_shift) goto with_shift; + #endif /* Handle most ASCII characters quickly, without calling mbrtowc(). */ if (is_basic (*iter->cur.ptr)) { @@ -145,8 +154,10 @@ mbuiter_multi_next (struct mbuiter_multi *iter) else { assert (mbsinit (&iter->state)); + #if !GNULIB_MBRTOC32_REGULAR iter->in_shift = true; with_shift: + #endif iter->cur.bytes = mbrtoc32 (&iter->cur.wc, iter->cur.ptr, strnlen1 (iter->cur.ptr, MB_CUR_MAX), &iter->state); @@ -156,7 +167,9 @@ mbuiter_multi_next (struct mbuiter_multi *iter) iter->cur.bytes = 1; iter->cur.wc_valid = false; /* Allow the next invocation to continue from a sane state. */ + #if !GNULIB_MBRTOC32_REGULAR iter->in_shift = false; + #endif memset (&iter->state, '\0', sizeof (mbstate_t)); } else if (iter->cur.bytes == (size_t) -2) @@ -188,8 +201,8 @@ mbuiter_multi_next (struct mbuiter_multi *iter) characters more quickly. */ #if !GNULIB_MBRTOC32_REGULAR if (mbsinit (&iter->state)) - #endif iter->in_shift = false; + #endif } } iter->next_done = true; @@ -204,9 +217,11 @@ mbuiter_multi_reloc (struct mbuiter_multi *iter, ptrdiff_t ptrdiff) MBUITER_INLINE void mbuiter_multi_copy (struct mbuiter_multi *new_iter, const struct mbuiter_multi *old_iter) { + #if !GNULIB_MBRTOC32_REGULAR if ((new_iter->in_shift = old_iter->in_shift)) memcpy (&new_iter->state, &old_iter->state, sizeof (mbstate_t)); else + #endif memset (&new_iter->state, 0, sizeof (mbstate_t)); new_iter->next_done = old_iter->next_done; mb_copy (&new_iter->cur, &old_iter->cur); @@ -214,10 +229,18 @@ mbuiter_multi_copy (struct mbuiter_multi *new_iter, const struct mbuiter_multi * /* Iteration macros. */ typedef struct mbuiter_multi mbui_iterator_t; +#if !GNULIB_MBRTOC32_REGULAR #define mbui_init(iter, startptr) \ ((iter).cur.ptr = (startptr), \ (iter).in_shift = false, memset (&(iter).state, '\0', sizeof (mbstate_t)), \ (iter).next_done = false) +#else +/* Optimized: no in_shift. */ +#define mbui_init(iter, startptr) \ + ((iter).cur.ptr = (startptr), \ + memset (&(iter).state, '\0', sizeof (mbstate_t)), \ + (iter).next_done = false) +#endif #define mbui_avail(iter) \ (mbuiter_multi_next (&(iter)), !mb_isnul ((iter).cur)) #define mbui_advance(iter) \ -- 2.39.5