InputText: optimization for large text: using memchr() instead of strchr() shaves 0.2 ms on 865k multi-line text case. Approximately 20%. (#7925)

This commit is contained in:
ocornut 2024-09-16 14:15:43 +02:00
parent 510b6adc9b
commit b53d91a4c4
2 changed files with 3 additions and 2 deletions

View File

@ -68,7 +68,7 @@ Other changes:
- InputText: internal refactoring to simplify and optimize the code. The ImWchar buffer has been - InputText: internal refactoring to simplify and optimize the code. The ImWchar buffer has been
removed. Simplifications allowed to implement new optimizations for handling very large text buffers removed. Simplifications allowed to implement new optimizations for handling very large text buffers
(e.g. in our testing, handling of a 1 MB text buffer is now 3 times faster in VS2022 Debug build). (e.g. in our testing, handling of a 1 MB text buffer is now 3 times faster in VS2022 Debug build).
This is the first step toward more refactorig. (#7925) [@alektron, @ocornut] This is the first step toward more refactoring. (#7925) [@alektron, @ocornut]
- InputText: added CJK double-width punctuation to list of separators considered for CTRL+Arrow. - InputText: added CJK double-width punctuation to list of separators considered for CTRL+Arrow.
- Misc: Made it accepted to call SetMouseCursor() with any out-of-bound value, as a way to allow - Misc: Made it accepted to call SetMouseCursor() with any out-of-bound value, as a way to allow
hacking in custom cursors if desirable. hacking in custom cursors if desirable.

View File

@ -5095,6 +5095,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
// FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8.
const char* text_begin = state->TextA.Data; const char* text_begin = state->TextA.Data;
const char* text_end = text_begin + state->CurLenA;
ImVec2 cursor_offset, select_start_offset; ImVec2 cursor_offset, select_start_offset;
{ {
@ -5119,7 +5120,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter. // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter.
searches_remaining += is_multiline ? 1 : 0; searches_remaining += is_multiline ? 1 : 0;
int line_count = 0; int line_count = 0;
for (const char* s = text_begin; (s = strchr(s, '\n')) != NULL; s++) // FIXME-OPT: memchr() would be faster? for (const char* s = text_begin; (s = (const char*)memchr(s, '\n', (size_t)(text_end - s))) != NULL; s++)
{ {
line_count++; line_count++;
if (searches_result_line_no[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_no[0] = line_count; if (--searches_remaining <= 0) break; } if (searches_result_line_no[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_no[0] = line_count; if (--searches_remaining <= 0) break; }