From cae184d7cfb721c8046bcf72987b8f54eb5d3258 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 3 Jan 2024 16:48:42 -0500 Subject: [PATCH] AK: Improve performance of StringUtils::find_last The current algorithm is currently O(N^2) because we forward-search an ever-increasing substring of the haystack. This implementation reduces the search time of a 500,000-length string (where the desired needle is at index 0) from 72 seconds to 2-3 milliseconds. --- AK/StringUtils.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp index 23d41c0335..baadb05163 100644 --- a/AK/StringUtils.cpp +++ b/AK/StringUtils.cpp @@ -412,10 +412,15 @@ Optional find_last(StringView haystack, char needle) Optional find_last(StringView haystack, StringView needle) { - for (size_t i = haystack.length(); i > 0; --i) { - auto value = StringUtils::find(haystack, needle, i - 1); - if (value.has_value()) - return value; + if (needle.length() > haystack.length()) + return {}; + + for (size_t i = haystack.length() - needle.length();; --i) { + if (haystack.substring_view(i, needle.length()) == needle) + return i; + + if (i == 0) + break; } return {};