From 5dfc24882fb9ed40c79e60963dbfdbccd3c82450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zadro=C5=BCny?= Date: Wed, 4 Dec 2024 14:29:49 +0100 Subject: [PATCH] improve `strings.index_multi` There's no point searching for substrings after lowest_index, so let's not. This significantly improves performance on long strings. --- core/strings/strings.odin | 3 ++- tests/core/strings/test_core_strings.odin | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index af93ff33c92..c014d2b2b8e 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1872,7 +1872,8 @@ index_multi :: proc(s: string, substrs: []string) -> (idx: int, width: int) { lowest_index := len(s) found := false for substr in substrs { - if i := index(s, substr); i >= 0 { + haystack := s[:min(len(s), lowest_index + len(substr))] + if i := index(haystack, substr); i >= 0 { if i < lowest_index { lowest_index = i width = len(substr) diff --git a/tests/core/strings/test_core_strings.odin b/tests/core/strings/test_core_strings.odin index 0d94b9c6215..0304ec22667 100644 --- a/tests/core/strings/test_core_strings.odin +++ b/tests/core/strings/test_core_strings.odin @@ -40,6 +40,25 @@ test_last_index_any_small_string_not_found :: proc(t: ^testing.T) { testing.expect(t, index == -1, "last_index_any should be -1") } +@test +test_index_multi_overlapping_substrs :: proc(t: ^testing.T) { + index, width := strings.index_multi("some example text", {"ample", "exam"}) + testing.expect_value(t, index, 5) + testing.expect_value(t, width, 4) +} + +@test +test_index_multi_not_found :: proc(t: ^testing.T) { + index, width := strings.index_multi("some example text", {"ey", "tey"}) + testing.expect_value(t, index, -1) +} + +@test +test_index_multi_with_empty_string :: proc(t: ^testing.T) { + index, width := strings.index_multi("some example text", {"ex", ""}) + testing.expect_value(t, index, -1) +} + Cut_Test :: struct { input: string, offset: int,